一、什么是数据结构
- 数据结构的起源 1968年,美国高德纳教授,《计算机程序设计艺术》第一卷《基本算法》,开创了数据结构和算法的先河 数据结构是研究数据之间关系和操作之间的学科,而非计算方法, 数据结构+算法=程序 美国沃斯提出,这句话揭示了程序的本质
- 数据结构相关基础概念 数据:所有能够输入到计算机中,能够被程序处理的描述客观事物的符号, 数据项:有独立含义的数据的最小单位 数据元素:组成数据的有一定含义的基本单位,也叫做节点、结点、记录 数据结构:相互之间存在一种或多种特定关系的数据元素的集合 算法:数据结构中所具备的功能,解决某种特定问题的方法
- 数据结构的三个方面: 数据的逻辑关系 数据的存储关系 数据的结构关系
二、数据结构的逻辑关系和存储关系
逻辑关系:
- 集合:数据元素同属一个集体,但元素之间没有任何关系
- 线性结构:数据元素之间存在一对一的关系
- 树形结构:数据元素之间存在一对多的关系
- 图形结构:数据元素之间存在多对多的关系
存储(物理)关系
- 顺序结构:数据元素存储在连续的内存中,用数据元素的相对位置来表示关系 优点:支持随机访问,查找效率极高、适合用于查找数据频繁的结构 缺点:插入、删除时效率低不方便,空间利用率低、内存大小要求高
- 链式结构:数据元素存储在彼此相互独立的内存中,每个独立的元素也叫做结点,每个结点中增加一项数据项用于存储其它相关结点的地址,以此表示结点之间的关系 优点:插入、删除更快、空间利用率极高、对内存大小要求低 缺点:不支持随机访问,只能从头到尾逐个访问
- 注意:逻辑结构、存储结构采用哪种,根据实现难度、空间、时间要求、操作习惯等方面综合考虑选择合适的结构
线性表 顺序 链式 树 链式 顺序 图 顺序+链式
三、数据结构的运算
1、创建数据结构 create
2、销毁数据结构 destroy
3、清空数据结构 clear
4、数据结构排序 sort
5、插入元素、删除元素 insert delete
6、访问元素(查看值)、查询元素(有没有值) access query
7、修改元素 modify
8、遍历数据结构 ergodic show print
四、顺序表和链式表实现
- 顺序表: 数据项: 存储元素的连续内存的首地址 表的容量 当前元素的数量 运算: 创建、销毁、清空、插入、删除、访问、查询、修改、排序、遍历、
- 注意: 1、要保持数据结构的连续性 2、不要越界
2.链式表:list 元素(结点)的数据项: 数据域:可以是任何类型的若干个数据项 指针域:指向下一个结点 由若干个结点通过指针域连接到一起就形成了链表
不带头结点的单链表: 第一个结点的数据域存储有效数据 缺点:添加、删除结点时,可能会修改指向第一个结点的指针,参数需要使用二级指针,才能更改指针的指向,比较麻烦
带头结点的单链表: 第一个结点的数据域不存储有效元素,仅仅只是使用它的指针域,永远指向链表的第一个数据有效的结点 优点:添加、删除时会比不带头结点的链表更方便 注意:其它操作要从头结点的下一个结点开始
二、功能受限的表结构
对表结构的部分功能加以限制,形成特殊的表结构
栈: 只有一个进出口的表结构 先进后出,FILO
顺序栈:
数据域: 存储元素内存的首地址 栈的容量 栈顶的位置(空增栈 满增栈) 运算: 创建、销毁、入栈、出栈、栈顶、栈满、栈空 栈的应用: 1、函数的调用、栈内存特点 2、生产者和消费者模型(仓库->栈) 3、表达式解析 3-3*20/2
链式栈:
栈结构数据项: 栈顶结点 结点数量 运算: 创建、销毁、入栈、出栈、栈空、栈顶
队列:有两个端口,一个入队,一个出队 先进先出 FIFO
顺序队列: 数据项: 存储元素的内存首地址 容量
队头下标:出队
队尾下标:入队
运算: 创建、销毁、入队、出队、队空、队满、查队头、查队尾、数量
顺序队列的注意点: 由一维数组+队头下标front+队尾下标tail组成,入队tail++,出队front++,为了让队列能够反复使用,我们把队列想象成一个环,因此当front和tail加1后都需要用队列容量求余再重新赋值 front = (front+1)%cal; tail = (tail+1)%cal;
如何判断队空、队满: 额外多申请一个元素的内存
队空:front == tail
队满:(tail+1)%cal = front
代价是空了一个位置不能使用,计算数量时较为麻烦
计算数量:(tail-front+cal)%cal
另一种方式是队列结构中多增加一项数据项用于记录队列中元素个数,判断队空或队满直接判断该数据项即可,更方便
链式队列:由链表结点组成的队列结构
数据项:
队头指针:
队尾指针:
结点数量 运算: 创建、销毁、队空、入队、出队、队头、队尾
队列应用:
1、消息队列 2、树的层序遍历使用队列 3、图的广度优先遍历使用队列 4、封装线程池、数据池