数据结构: Data Structure = (D,L,S,O)
D : Data数据
L:逻辑关系
S: 存储结构
O:规定的结构
存储结构:
1)顺序存储
2)链式存储
抽象数据结构: (D,L,O)
没有存储结构
算法分析:
时间复杂度:需要的时间资源,T(n)
空间复杂度:需要的空间
依赖于问题规模,算法的输入,算法本身的函数
C = F(N,I,A)
规定输入:
- 最坏情况
- 最好
- 平均情况
渐进表达
n^2 + 100n步的复杂度和 2*n^2一样
线性表
特点:
- 数据类型相同
- 位序从1开始
- 每个元素都有唯一的前驱和后继
基本操作:
- 结构初始化
初始化(成功,失败,内存不足,内存溢出) - 结构销毁
清空,删除元素 - 引用型操作
求长度,定位(按照查询的值定位到元素的位置,返回位置),取元素(按照位置,找到元素,返回数值),求前驱,求后继 - 加工型操作
插入,删除
合并线性表(A和B)和合并有序表的区别(C和D):
合并线性表是将两个表合并成一个表,且将合并结果存放在两表的一个中;合并线性表的过程中,取B表中的元素(n个元素)与A表(m个元素)进行比较,查找该元素是否在A表中,则这里涉及两层循环,外层取B中元素,长度设为n,内层,定位查找locate的次数。若B中的元素均在A表中的前面(最好情况),定位后进行系数加一,则从B表中取第一个元素定位需要的次数为1,从B中取第二个元素定位的次数为2,以此类推,从B中取第n个元素需要的次数为n,则在最好的情况下,其操作次数总共为(n+1)×n/2;(最坏情况下)若B与A相交为空,则从B中取出第一个元素定位需要的次数为A表的长度m,定位后将其插入A表,则A表长度变为m+1,取出第二个元素定位需要的次数为m+1,以此类推,取出第n个元素的次数为(n+m-1),则在最坏的情况下,其操作次数总共为m+m+1+…+ (n+m-1) = n×m +n×(n-1)/2。所以当n的值越小,操作次数越小,所以两个线性表合并时,把元素少的插入元素多的会更省时间!!
则合并线性表的时间复杂度为O(n∧2)。
合并有序表:是比较有序表C与D中元素的大小,小的插入到新的链表中,这里就一层循环,当C或D中的一个线性表插入完成后,则将另一表剩余的元素依次插入到新链表中,这样的操作次数为两表中较长一表的元素个数。比如C长度为I,D表长度为J,若I>J,则其时间复杂度为O(I)。
线性表的查找:
线性表的插入:
因为插入时,要逐个挪动插入位置后的元素,时间复杂度为O(n/2),效率较低
线性表的链表形式:
分为带头节点 和 不带头结点的,两个情况操作第一个数据的方法不一样
单向链表(带头,带尾)
双向链表
循环链表
静态链表(不支持指针的)
栈(LIFO)
栈的特点是,在表的同一端进行插入或者删除操作的线性表,可以用来把数据逆序输出
栈顶: 进行插入或删除的一端
栈底: 底端
空栈: 没有数据元素
入栈: 插入数据元素
出栈: 删除数据元素
栈初始化
栈销毁
栈深度
入栈
出栈
取栈顶的值:
溢出:
上溢:当空间全部占满后再入栈产生的溢出
下溢:空栈时再出栈
多个顺序栈空间共享:
可以将数组头 和 数组尾作为两个栈的栈底,栈1底入栈时,下标加1;栈2底入栈时,下标减1
以上使用的是数组,以下使用单链表实现栈
链栈:入栈,出栈,求栈顶的时间复杂度都是 O(1),并且不被预估空间所限制(顺序栈被预估空间限制)
a5为最先入栈的元素
入栈:
出栈:
取栈顶元素:
队列:
定义:只能在表的一端进行插入,表的另一端进行删除的线性表,例如RingBuffer
队尾(rear):允许插入的一端
队头(front):允许删除的一端
特点先进先出,数据为固定长度的话,就用顺序存储(数组),假如长度不能确定的话,使用链式存储
链式存储