- 线性表:零个或多个具有相同类型的结点组成的有序集合。
线性表的顺序存储结构
- 用一组连续的存储空间依次存储线性表的元素,逻辑顺序与物理顺序相同。
- 优点:简单、易于实现,可以随机访问表中任一元素。
- 缺点:容量不易扩充,插入、删除麻烦,需移动元素。
线性表的链接存储结构
- 用一组任意存储单元存储线性表的数据元素,逻辑顺序可以和物理顺序不同。
- 优点:插入、删除方便,能合理利用空间。
- 缺点:从一个结点出发,只能访问到链接在它后面的结点。
循环链表
- 令表尾结点的next域存放指向表头结点的指针,而不是存放空指针。
- 循环链表表头:哨位结点(数据为空,指向第一个数据项)
- 判断表尾:p->next==header
- 判断表空:header->next==header
双向循环链表
- 链表结构
- 判断表空:header->left== header->right== header
- 对称性:p->right->left = p->left->right =p
对比分析——空间效率
- 顺序表:当表中元素较少时,顺序表中的很多空间处于闲置状态,造成了空间浪费。
- 链表:所占用空间需要动态申请,不存在空间浪费问题,但是链表需要在每个结点上附加一个指针。
- 线性表长度较大时,顺序表的空间效率较高;线性表长度较小时,链表的空间效率较高。
对比分析——时间复杂性
- 顺序表:随机存取容易,插入、删除麻烦,需要移动若干元素。
- 链表:无法随机存取,必须从表头遍历,直至找到要存取的元素,但是插入删除简便。
- 当线性表经常需要进行插入、删除操作时,链表时间复杂性较小,效率较高;当线性表经常需要存取,且存取操作比插入删除操作频繁的情况下,顺序表的时间复杂度较小,效率较高。
栈和队列:操作受限的线性表
堆栈
- 栈:插入和删除只能在其一端进行,按先进后出或后进先出的原则进行操作。
栈的封闭性:在一个栈中,出入口处称为栈顶,栈内最深处称为栈底。除栈顶元素外,其他元素不会被改变。因而栈的封闭性非常好,使用起来非常安全。
堆栈的顺序存储
- 使用数组存放栈元素,栈的规模必须小于等于数组规模;等于时,不能再向栈中插入元素。
- 堆栈空:top=-1
- 堆栈满:top=maxstacksize-1
* 用数组实现栈的效率很高,但如果同时使用多个栈,顺序栈将浪费大量空间。
堆栈的链接存储
- 栈顶对应链表表头。
顺序栈和链式栈的比较
- 在空间复杂性上
顺序栈必须初始就申请固定的空间,栈不满时必然造成空间浪费。
链式栈所需空间根据需要随时申请,代价是为每个元素提供空间以存储其next指针域。 - 在时间复杂性上
顺序栈和链式栈的时间复杂性均为O(1)
堆栈的应用——语法检查(括号匹配)
堆栈的应用——十进制数转换成r进制数
堆栈的应用——中缀表达式转后缀
堆栈的应用——后缀表达式求值
队列
- 队列:插入在一端进行而删除在另一端进行的线性表,按先进先出的原则进行。进行删除的一端称为队首,进行插入的一端称为队尾。
- 与栈类似,队列的封闭性也非常好。栈能对输入序列起求逆作用;队列对输入序列起缓冲作用。
队列的顺序存储
- front:永远指向队首元素
- rear:永远指向队尾元素的下一地址
- 初始:rear=front=NULL
删除情况1
- 插入:rear=rear+1
- 删除:front=front+1
front前的空间无法利用
删除情况2
- 插入:rear=rear+1
- 删除:rear=rear-1,所有元素向前移动,front总等于0
所有元素地址都必须改变,效率低下。
循环队列
- front 指定队首位置,删除一个元素就将front顺时针移动一位。
front=(front+1)MOD maxqsize - rear指向元素要插入的位置,插入一个元素就将rear顺时针移动一位。
rear=(rear+1)MOD maxqsize - count 存放队列中元素的个数
- 队空:count=0
- 队满:count=maxqsize