数据结构-线性表
线性表
线性表是典型线性数据结构。
线性表是由n(n≥0)个数据元素组成的一个有限序列,线性表中数据元素的个数n称为线性表的长度。当n=0时,称为空表。
非空线性表满足线性结构的三个特性。
线性表的数据元素可以是由一个数据项组成的简单数据元素,也可以是多个数据项组成的复杂数据元素。
线性表的表示方式:
其中ei(i=1,2,3...n),e1为首结点,en为尾结点。线性表中一个数据元素称为一个结点。
线性表的操作:
创建线性表;
删除线性表;
插入新元素;
判断线性表是否为空;
计算线性表长度;
取某一个元素;
按照关键字查找指定元素;
删除第k个元素;
删除元素根据关键字;
输出线性表;
线性表的抽象数据类型定义:数据元素用T表示,List是线性表的抽象数据类型名
线性表的顺序存储:顺序表
存放线性表最简单的方法是顺序存储。
高级语言的一维数组和线性表的逻辑结构相似,通常用定义一个一维数组来实现线性表的顺序存储。
把线性表的结点按照逻辑顺序一次存放在一组地址连续的存储单元里就构成了线性表的顺序存储,采用顺序存储的线性表叫顺序表。
线性表的顺序存储结构的特点:
线性表中所有元素所占的存储空间是连续的。
线性表的逻辑顺序与物理顺序一致。
数组中的每个元素的位置可以用公式来确定。
使用C++声明顺序表类模板
顺序表的实现
顺序表插入算法实现:
1、判断插入位置的合理性以及表是否已满
2、从最后一个元素开始,将每个元素向后移动一个位置,直到第i个位置空闲
3、在第i个位置放入新元素x
4、将线性表长度加1
顺序表的删除算法实现:
1、判断删除位置的合理性
2、从第i+1个元素开始,依次向后直到最后一个元素,将每个元素向前移动一个位置
3、将线性表长度减1
顺序表类操作的实现
结点类模板 头文件
复杂数据元素顺序表的应用问题
顺序表优缺点
优点:简单、存储密度大、空间利用率高、存储效率高。
缺点:顺序表中插入和删除操作时,需要移动大量的数据元素,浪费时间;
实际应用中顺序表的长度不好估计,往往需要为顺序表分配足够大的内存空间,造成浪费。
总结:对于元素变动频繁、长度变化比较大的线性表,不宜采用顺序存储结构,适合采用链式存储结构。
线性表的链式存储结构:线性链表
线性链表是用一组任意的存储单元存储线性表中的数据元素。
线性链表中的结点可以是连续的,也可以是不连续的,可以零散分布在内存中任意位置中。
线性链表的数据元素的逻辑顺序和物理顺序不一定相同。
线性链表包括单向链表、循环链表和双向链表。
链式存储结构需要借助C++高级语言中的指针类型来实现。
链式存储结构:通过结点的指针域将n个结点按其逻辑结构连接在一起的数据存储结构,称为链式存储结构。
链式存储结构中每一个数据元素对应一个存储单元,这种存储单元称为存储结点,简称结点。
每个结点分两部分:一部分是数据域,存放数据元素的值;一部分是指针域,存放指向与该结点在逻辑上相连的其他结点。
对于线性表,指针域用于指向该结点的前一个或者后一个结点。
单向链表
线性链表中,用一个专门的指针指向线性表第一个结点,每一个结点的指针都指向它的下一个结点,最后一个结点的指针为空(null或0),表示链表终止,这样的的链表称为单向链表。
链式结构,在第一个结点前面加一个头结点程序会变得简洁,程序运行速度会提高。所以链式存储结构一般都采用带有头结点的结构。
- 为什么加头结点会简洁会提高运行速度?
单线链表结点类模板LinkNode
单向链表插入算法
单向链表中,表中已经有n个元素,往第k个位置处插入结点NewNode时:
①当k>n+1或者k<1时,插入位置不正确,报错;
②当时空表且k=1,只需要将head->next指向新节点即可;
③当不是空表且k=1,需要将新节点的next指针指向第一个元素结点,再将头结点的指针域指向newNode结点;
④当1<k<=n,将newNode的next指针指向第k个元素结点,将第k-1个元素结点的next指针指向newNode结点。
单向链表删除操作
单向链表中,表中已经有n个元素,要删除第k个元素:
①当k>n+1或者k<1时,由于没有第n+1或第0个元素,报错;
②当k=1时,将头结点的指针域指向第二个结点,然后释放第k个结点;
③单1<k<n时,将第k-1个元素结点的指针域指向第k+1个元素结点,然后释放第k个结点;
④当k=n时,将第n-1个结点的next指针赋值为NULL,然后释放第k个结点。
实现插入新数据元素
实现按位置删除
实现按关键字删除
单向链表基本操作的实现
循环链表
将单向链表最后一个结点的指针指向头结点,这样整个链表就构成一个循环,这种链式存储结构称为单向循环链表,简称循环链表。
只有头结点的循环链表称为空循环链表。
循环链表中至少有一个结点存在,使空表与非空表的运算一致。
和单向链表的区别:循环链表空表的条件:head->next==head; 单向链表空表的条件:head->next==NULL。
双向链表
双向链表每个结点包含两个指针域,一个指针指向其前驱结点(prev指正),一个指针指向其后继结点(next指针)。
将双向链表的的第一个结点的prev指针指向最后一个结点,将最后一个结点的next指针指向第一个结点,就构成了双向循环链表。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!