《数据结构》--顺序表

C语言语法基础到数据结构与算法,前面已经掌握并具备了扎实的C语言基础,为什么要学习数据结构课程?--我们学完本章就可以实践一个:通讯录项目

简单了解过后,通讯录具备增加、删除、修改、查找联系人等操作。要想实现通讯录项目必须有两个技术关键:(1)C语言语法基础(2)数据结构 之 顺序表/链表。


一、初步了解数据结构

什么是数据结构?数据结构就是“数据”与“结构”两个词组合而来。

什么是数据:常见的数值1、2、3......、教务系统里保存的用户信息(姓名、性别、年龄、学历等)、网页里的图片、视频、文字等等,都是数据。(我们知晓的所有信息都可以称之为数据,数据在计算机中存储的方式都是二进制数字,包括图文、视频等)

什么是结构:当我们想要大量使用同一类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。

概念:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在的一种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由哪部分构成、以什么方式构成、以及数据元素之间呈现的结构。

小结:

1.能够存储数据(如顺序表、链表等结构)

2.存储的数据能够方便查找

为什么需要数据结构?通过数据结构可以有效的将数据组织和管理在一起。按照我们的方式任意对数据进行增删查改等操作。最基础的数据结构:数组。

【思考】有了数组,为什么还要学习其它数据结构?

假定数组有10个空间,已经使用了5个,向数组中插入数据的步骤有:

1.求数组的长度(求总长是为了判断有效个数与最大长度是否相等,数组满员还能继续插入吗?) 2.求数组的有效数据个数 3.向下标为数据有效个数的位置插入数据

假设数据量非常的庞大,频繁的获取数组有效个数会影响程序执行效率。

结论:最基础的数据结构能提供的操作已经不能完全满足复杂算法的实现。


二、顺序表

1.顺序表的概念及结构

顺序表是一种线性表。线性表(linear list)是n个相同特性的数据元素的有限序列。线性表是一种在实际中广泛应用的数据结构,常见的线性表包括:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上的存储方式通常是顺序(数组)存储和链式存储。

如何理解逻辑结构和物理结构?下面给大家画一张图:

第一种就是物理顺序和逻辑顺序一致,在一段连续的空间中依次存放数据。第二种就是这些数据逻辑上是一条线,但由于存储的位置不连续,在忽略其它空间的情况下,将这些空间取出并将其放置到一条直线上就可以验证它的线性存储形式是逻辑线性,物理上的存储是不确定的。

2.顺序表分类

顺序表和数组的区别:顺序表的底层结构是数组,对数组的封装,实现了常用的增删查改等接口。

分类:静态顺序表-动态顺序表

//静态顺序表
typedef int DataType;
#define SQLIST_INIT_LENGTH 10
typedef struct SqList{DataType arr[SQLIST_INIT_LENGTH];size_t _size;//有效数据个数,每插入一个数据就会+1,用来记录
}SL;
//静态顺序表缺陷:空间给少了不够用,给多了造成空间浪费
//动态顺序表--按需分配
typedef struct SqList{DataType* arr;size_t _size;//有效数据个数size_t _capacity;//空间容量
}SL;

3.动态顺序表的基本操作

#define LIST_INIT_SIZE 10
typedef int DataType;
typedef struct SqList{DataType* arr;size_t size;//有效数据个数size_t capacity;//空间容量
}SL;//判空、取长、寻值
bool isEmpty(SL s);
int GetSize(SL s);
int SLFind(SL s,DataType data);//初始化与销毁
void SLInit(SL* s);
void SLDestroy(SL* s);
//打印
void SLPrint(SL s);
//扩容
void SLCheckCapacity(SL* s);
//修改指定位置的值
void UpdateNode(SL* s,int index,DataType data);//指定位置之前插入/删除数据
void SLInsert(SL* s,int index,DataType data);
void DeleteByIndex(SL* s,int index);
//按值删除数据
void DeleteByData(SL& s,DataType data);//增删操作也可以有下面的几种
//头插、头删、尾插、尾删
void SLInsert_Head(SL* s,DataType data);
void SLDelete_Head(SL* s);
void SLInsert_Tail(SL* s,DataType data);
void SLDelete_Tail(SL* s);

 三、动态顺序表的实现

1.顺序表的判空操作

顺序表的内容是否为空主要就是看里面的动态数组是否指向空指针。然后返回这个表达式的结果(布尔类型)。

bool isEmpty(SL s)
{return (s.arr == nullptr);
}

2.顺序表的长度

我们说的顺序表的长度是有效数据个数而非顺序表的空间总量 。所以我们返回的就是顺序表内部的size属性。

int GetSize(SL s)
{return s.size;
}

3.查找某值在顺序表的位置

查找某值在顺序表的位置时,首先判断顺序表是不是空的,如果是空的,那就没必要再继续了,直接返回-1。否则,循环遍历直至顺序表中顺组的有效长度的最后一个值。如果循环结束仍未找到,返回-1。那么综上返回-1就代表表内无该元素。

int SLFind(SL s, DataType data)
{if (isEmpty(s))return -1;else{for (int i = 0; i < s->size; i++) {if (*(s->arr + i) == data) {return i;}}}return -1;
}

4.顺序表的初始化与销毁

初始化时使用宏定义的初始化长度LIST_INIT_SIZE,使用malloc为数组申请一定长度的空间,然后对该表进行判断,如果仍然为空说明malloc申请空间时由于某些原因申请失败了,离开程序。否则就将顺序表的最大长度设为初始值,有效长度设为0。

销毁顺序表时,将顺序表长度和空间容量都置零,令数组指针指向NULL(按理来说nullptr更为严谨)。最后使用free释放内存空间。

	//初始化顺序表:给arr开辟10个空间void SLInit(SL* s){s->arr = (DataType*)malloc(sizeof(DataType) * LIST_INIT_SIZE);if (isEmpty(*s))exit(OVERFLOW);//s->arr = new DataType[LIST_INIT_SIZE];s->capacity = LIST_INIT_SIZE;s->size = 0;//尚未存储数据}//销毁顺序表void SLDestroy(SL* s){assert(s->arr);//在头文件<assert.h>中s->capacity = s->size = 0;s->arr = NULL;free(s->arr);cout << "销毁完毕" << endl;}

5.顺序表打印

如果顺序表为空,那还打印什么,直接告诉用户顺序表为空就可以了。非空的话,那就循环遍历顺序表的有效数据,将其中存储的值依次打印出来。

void PrintSqlist(SL s)
{if (isEmpty(s))cout << "顺序表为空";else {for (int i = 0; i < s.size; i++)cout << *(s.arr + i) << " ";}cout << endl;
}

6.顺序表插入数据

此处涉及到一个扩容的问题:当有效长度与最大容量相等时,说明顺序表满了,需要使用realloc动态扩容,考虑到不断扩容会导致效率变低或者出现问题,我们每次表满时直接选择二倍扩容。

//尾插
void SLInsert_Tail(SL* s, DataType data)
{if (isEmpty(*s)) {SLInit(s);//如果顺序表为空,则开辟一个顺序表}if ((s->size) == (s->capacity)){//2倍扩容DataType* tmp = (DataType*)realloc(s->arr, (s->capacity * 2) * sizeof(DataType));assert(tmp);//判断指针是否为空s->arr = tmp;//(s->capacity) *= 2;}*(s->arr + s->size) = data;(s->size)++;
}//指定位置插入
void SLInsert(SL* s, int index, DataType data)
{if (isEmpty(*s)) SLInit(s);if (index < 0 || index > s->size) return;if (s->size == s->capacity){int newcapacity = s->capacity * 2;DataType* tmp = (DataType*)realloc(s->arr, sizeof(DataType) * newcapacity);assert(tmp);s->arr = tmp;}for (int i = s->size; i >= index; i--){s->arr[i + 1] = s->arr[i];}s->arr[index] = data;s->size++;
}

7.顺序表删除数据

	//删除顺序表第index位数据(按位删)
void DeleteByIndex(SL* s, int index)
{if (isEmpty(*s)|| index > s->size||index < 0)cout << "空表或索引溢出" << endl;else {for (int i = index; i < (s->size); i++) {DataType tmp = *(s->arr + i);*(s->arr + i) = *(s->arr + i + 1);*(s->arr + i + 1) = tmp;}(s->size)--;}cout << "删除成功" << endl;
}//删除顺序表数据data(按值删)
void DeleteByData(SL& s, DataType data)
{if (isEmpty(s))cout << "空表" << endl;else {for (int i = 0; i < s.size; i++){if (*(s.arr + i) == data) {for (int j = i; j < s.size; j++){DataType tmp = *(s.arr + j);*(s.arr + j) = *(s.arr + j + 1);*(s.arr + j + 1) = tmp;}s.size--;		}cout << "删除完毕" << endl;}}
}

8.修改顺序表内容

void UpdateNode(SL* s, int index, DataType data)
{if (isEmpty(*s))cout << "顺序表为空" << endl;else{*(s->arr + index) = data;cout << "修改成功" << endl;}
}

9.顺序表扩容

扩容操作参考插入时的特殊处理。


我们在下节的项目实战中完成顺序表实现通讯录。(大家先试着完成写一写自己的通讯录系统,独立的完成每一个小项目才能为完成大项目积累经验)。加油各位!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/47292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习笔记—100页Opencv详细讲解教程

目录 1 创建和显示窗口... - 4 - 2 加载显示图片... - 6 - 3 保存图片... - 7 - 4 视频采集... - 8 - 5视频录制... - 11 - 6 控制鼠标... - 12 - 7 TrackBar 控件... - 14 - 8.RGB和BGR颜色空间... - 16 - 9.HSV和HSL和YUV.. - 17 - 10 颜色空间的转化... - 18 - …

数据结构——栈的实现(java实现)与相应的oj题

文章目录 一 栈栈的概念:栈的实现&#xff1a;栈的数组实现默认构造方法压栈获取栈元素的个数出栈获取栈顶元素判断当前栈是否为空 java提供的Stack类Stack实现的接口&#xff1a; LinkedList也可以当Stack使用虚拟机栈&#xff0c;栈帧&#xff0c;栈的三个概念 二 栈的一些算…

JetBrains IDE 使用git进行多人合作开发教程

以下DEMO可以用于多人共同开发维护一个项目时&#xff0c;使用Git远程仓库的实践方案 分支管理 dev&#xff1a;开发分支test&#xff1a;测试分支prod&#xff1a;生成分支 个人开发也最起码有一个masterdev&#xff0c;作为主分支和当前开发分支。master永远是稳定版本&am…

花几千上万学习Java,真没必要!(十九)

1、StringBuilder&#xff1a; 测试代码1&#xff1a; package stringbuilder.com; import java.util.ArrayList; import java.util.List; public class StringBuilderExample { public static void main(String[] args) { // 初始化StringBuilder StringBuilder sb n…

腾讯会议产品策划的成长之路:从万字文档到功能落地的实战经验

腾讯会议产品策划的成长之路&#xff1a;从万字文档到功能落地的实战经验 在腾讯会议的产品团队中&#xff0c;有这样一位产品策划&#xff0c;他以其出色的逻辑思维、全局观念以及扎实的执行力&#xff0c;在团队中发挥着举足轻重的作用。他就是林陪同&#xff0c;一个自称“会…

css font 优化

文章目录 使用 font-display 控制字体加载预加载关键字体选择合适的字体文件类型按需创建字体文件HTTP 缓存优化 使用 font-display 控制字体加载 避免字体加载导致的空白 block&#xff1a;浏览器在短暂的阻塞期内不显示任何文本&#xff0c;直到字体加载完成。这可能导致页…

JAVA进阶学习12

文章目录 一、File类1.1 File对象的构造1.2 File对象的常见方法判断功能的方法获取功能的方法绝对路径和相对路径创建删除功能的方法 1.3 File的常用遍历方法1.4 File获取并遍历的其他方法1.5 用法举例二、IO流2.1 IO的分类2.2 字节流的方法概述2.2.1 FileOutputStream2.2.2 Fi…

如何配置Memcached以减少对数据库的直接访问

如何配置Memcached以减少对数据库的直接访问 1. 引言 在现代应用程序中&#xff0c;数据库通常是性能瓶颈的主要来源之一。通过使用Memcached&#xff0c;开发者可以显著减少数据库的负载&#xff0c;提高应用程序的响应速度。本文将详细介绍如何配置Memcached&#xff0c;以…

UE4-字体导入

一.字体导入 方法一&#xff1a; 然后通过导入将自己想要的字体导入到项目中&#xff0c;也可以直接将我们放在桌面的字体直接拖入到我们的内容浏览器中。 但是要注意想要发售游戏的话不可以这样导入微软的字体&#xff0c;因为Windows自带基本都有版权&#xff0c;所以最…

odoo17创建一个默认UI视图

XML 数据文件 当要加载的数据具有简单格式时&#xff0c;CSV 格式很方便。当格式更复杂时&#xff08;例如&#xff0c;加载视图或电子邮件模板的结构&#xff09;&#xff0c;我们使用 XML 格式。例如&#xff0c;此帮助字段包含 HTML 标记。虽然可以通过 CSV 文件加载此类…

明星应援系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;线上应援管理&#xff0c;线下应援管理&#xff0c;应援物品管理&#xff0c;购买订单管理&#xff0c;集资应援管理&#xff0c;集资订单管理&#xff0c;市集订单管理&#xff0…

极致竞争思维

老板请了几个毕业生&#xff0c;培训了一年&#xff0c;他们现在对业务的熟悉程度比我都熟悉多了&#xff0c;只是基本功不扎实&#xff0c;做出来的东西有很多问题。 老板请我来&#xff0c;给了我一个硬件总监的位置&#xff0c;实际上是要对他的整个系统做出诊断。 也是难为…

【QT】线程控制和同步

目录 概述 QThread常用API 线程使用 创建一个QThread的子类 主线程启动线程 线程安全 互斥锁 QMutex 使用示例&#xff1a;两个线程一个共享静态变量进行 线程子类创建 主线程调用 QMutexLocker 条件变量 信号量 概述 在 Qt 中&#xff0c;多线程的处理⼀般是…

【CSS in Depth 2 精译_020】3.3 元素的高度

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

【proteus经典实战】定时器控制交通灯指示灯

一、简介 基于8051系列单片机实现&#xff0c;旨在模拟一个简单的交通灯系统&#xff0c;实现红、黄、绿灯的交替亮灭。使用了特殊功能寄存器&#xff08;SFR&#xff09;和位操作来控制硬件&#xff0c;使用定时器0的中断功能来控制交通灯信号的切换。通过软件控制&#xff0…

解决selenium打印保存为PDF时图片未加载成功的问题

使用selenium打印网页时&#xff0c;如果程序运行很快的话&#xff0c;可能会导致图片没有加载成功即进行了保存&#xff0c;出现这个问题最初的思考是在执行打印任务时使用js进行强制等待&#xff0c;后发现实现效果并不好。在加载页面时使用自动下滑的方式将网页拉到底&#…

uniapp动态计算并设置元素高度

<template><view><scroll-view id"sv-box" :scroll-y"true" :style"{height:navHeightpx}"></scroll-view><view id"btn-box"><button>取消</button><button>确认</button><…

Linux Vim教程(三):插入模式与命令模式

目录 1. Vim的基本模式介绍 2. 插入模式 2.1 进入插入模式 2.2 退出插入模式 2.3 插入模式下的快捷键 2.4 插入模式中的光标移动 3. 命令模式 3.1 进入命令模式 3.2 常用命令 3.3 搜索和替换 3.4 其他有用的命令 3.5 配置与优化 3.5.1 自动补全 3.5.2 自定义快捷…

【前后端联调】HttpMessageNotReadableException

【前后端联调】HttpMessageNotReadableException 01 问题描述 在前后端联调时产生的问题&#xff0c;关键是下面这句翻译JSON解析错误&#xff1a;无法构造“java.util.ArrayList”的实例 org.springframework.http.converter.HttpMessageNotReadableException: JSON parse …

记录贴-NGINX相关

链接: NGINX相关配置信息说明