《数据结构》--顺序表

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;一个自称“会…

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…

UE4-字体导入

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

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

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

【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 相对…

在 CI/CD 中怎么使用 Docker 部署前端项目?

本项目代码已开源&#xff0c;具体见&#xff1a; 前端工程&#xff1a;vue3-ts-blog-frontend 后端工程&#xff1a;express-blog-backend 数据库初始化脚本&#xff1a;关注公众号程序员白彬&#xff0c;回复关键字“博客数据库脚本”&#xff0c;即可获取。 前言 在上一篇文…

快速上手AI指令:打造个性化智能交互体验的全面指南

快速上手AI指令&#xff1a;打造个性化智能交互体验的全面指南 一、初识文心一言1.1 文心一言简介1.2 文心一言的特点 二、准备工作2.1 获取访问权限2.2 熟悉界面布局2.3 了解基础指令 三、基础指令操作3.1 问答互动3.2 文本创作3.3 任务规划 四、进阶指令操作4.1 复杂查询4.2 …

Python酷库之旅-第三方库Pandas(035)

目录 一、用法精讲 106、pandas.Series.iloc方法 106-1、语法 106-2、参数 106-3、功能 106-4、返回值 106-5、说明 106-6、用法 106-6-1、数据准备 106-6-2、代码示例 106-6-3、结果输出 107、pandas.Series.__iter__魔法方法 107-1、语法 107-2、参数 107-3、…

Java程序的故障排查

文章目录 Linux命令关机/重启/注销系统信息和性能查看磁盘和分区⽤户和⽤户组⽹络和进程管理常⻅系统服务命令⽂件和⽬录操作⽂件查看和处理打包和解压RPM包管理命令YUM包管理命令DPKG包管理命令APT软件⼯具 JDK命令jpsjstatjinfojmapjhatjstackjcmdjconsole 分析工具VisualVME…

自动驾驶-预测概览

通过生成一条路径来预测一个物体的行为&#xff0c;在每一个时间段内&#xff0c;为每一辆汽车重新计算预测他们新生成的路径&#xff0c;这些预测路径为规划阶段做出决策提供了必要信息 预测路径有实时性的要求&#xff0c;预测模块能够学习新的行为。我们可以使用多源的数据…

超简单安装指定版本的clickhouse

超简单安装指定版本的clickhouse 命令执行shell脚本 idea连接 命令执行 参考官网 # 下载脚本 wget https://raw.githubusercontent.com/183461750/doc-record/d988dced891d70b23c153a3bbfecee67902a3757/middleware/data/clickhouse/clickhouse-install.sh # 执行安装脚本(中…

【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)

0x01 产品简介 NETGEAR WN604是一款由NETGEAR&#xff08;网件&#xff09;公司生产的无线接入器&#xff08;或无线路由器&#xff09;提供Wi-Fi保护协议&#xff08;WPA2-PSK, WPA-PSK&#xff09;&#xff0c;以及有线等效加密&#xff08;WEP&#xff09;64位、128位和152…

亲测--linux下安装ffmpeg最新版本---详细教程

下载地址 Download FFmpeg 下载最新的https://ffmpeg.org/releases/ffmpeg-7.0.1.tar.xz 上传到服务器 解压 tar xvf ffmpeg-7.0.1.tar.xz 编译 cd ffmpeg-7.0.1 ./configure --prefix=/usr/local/ffmpeg make && make install 报错: 解决:在后面加 跳过检测…

【Word】——小技巧

1.PDF相关转换word PDF转换成Word在线转换器 - 免费 - CleverPDF 2. word插入公式 1.软件推荐&#xff08;免费&#xff09; 可直接将图片&#xff0c;截屏公式转为word标准规范形式 2.网址推荐 在线LaTeX公式编辑器-编辑器 &#xff08;每天有免费使次数&#xff09; 3.…

Matlab演示三维坐标系旋转

function showTwo3DCoordinateSystemsWithAngleDifference() clear all close all % 第一个三维坐标系 origin1 [0 0 0]; x_axis1 [1 0 0]; y_axis1 [0 1 0]; z_axis1 [0 0 1];% 绕 x 轴旋转 30 度的旋转矩阵 theta_x 30 * pi / 180; rotation_matrix_x [1 0 0; 0 cos(th…

Linux服务器配置Python+PyTorch+CUDA深度学习环境

参考博主 Linux服务器配置PythonPyTorchCUDA深度学习环境_linux cuda环境配置-CSDN博客 https://blog.csdn.net/NSJim/article/details/115386936?ops_request_misc&request_id&biz_id102&utm_termlinux%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E6%8C%89pytorch%20…