1.栈
1.1栈的定义
栈(stack)是限定仅在表尾进行出入和删除操作的线性表。(后进先出,Last In First Out)
栈顶(top)、栈底(bottom)
空栈:top=-1
1.2栈的抽象数据类型
栈是一种特殊的线性表,插入和删除操作只能在表尾进行(top),插入(push,进栈)、删除(pop,出栈)。
Data
同线性表,元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitStack(S); 初始化,建立空栈S
DestroyStack(S); 销毁栈
ClearStack(S); 清空栈
StackEmpty(S); 判断是否空栈
GetTop(S,e); 非空栈,用e返回栈顶元素
Push(S,e); 插入
Pop(S,e); 删除
StackLength(S); 返回元素个数
1.3栈的顺序存储
考虑两种情况,空栈和栈满,需提前确定数组存储空间,针对两个相同类型的栈,可以共享空间。
两栈共享空间
栈满:top1+1=top2
栈空:top1=-1,top2=n
1.4栈的链式存储
对于栈来说,因为已经有了栈顶在头部了,单链表中的头结点也就没有意义了。对于链栈来说,不需要头结点。
对于链栈来说,没有栈满的情况(除非内存没有可以使用的空间了,这时系统可能会死机崩溃)。
空栈:top=NULL
1.5递归
1.5.1斐波那契数列
如果兔子在出生两个月后就有繁殖能力,一对兔子可以生出一对小兔子,假设所有的兔子都不死,那么一年后可以繁殖多少对兔子?
1->1->2->3->5->8->13…
1.5.2递归定义
注意:递归条件,避免掉进无穷的递归中
系统中常见的撤销操作,存储数据,可以使用栈这样的数据结构。
1.6栈的应用
四则运算表达式求值
1.6.1中缀表示法
即平常所见的标准的四则运算的表达式
1.6.2后缀(逆波兰)表示法
对于一个式子,括号是成对出现的,对于多重括号,也是完全嵌套匹配的。可以使用栈结构,遇到左括号就入栈,出现右括号就出栈,期间进行计算。栈在这个过程中,是由空到有元素到空的过程。
针对四则运算,需要先进行乘除,后计算加减。后缀表达式,将所有符号放在运算数字后面。
2.队列
2.1队列的定义
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。(先进先出,First In First Out)
队头:允许删除的一端
队尾:允许插入的一端
2.2队列的抽象数据类型
队列也是一种特殊的线性表,在队尾进行插入操作,而在队头进行删除操作。
Data
同线性表,元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitQueue(Q); 初始化
DestroyQueue(Q); 销毁
ClearQueue(Q); 清空
QueueEmpty(Q); 判断是否空
GetHead(Q,e); 非空,用e返回队头元素
EnQueue(Q,e); 插入队尾
DeQueue(Q,e); 删除队头
StackLength(Q); 返回元素个数
2.3队列的顺序存储
队头:front
队尾:rear
空:front和rear均指向下标为0的位置。
删除元素front后移,插入元素rear后移,可能产生假溢出(数组下标较小的位置为空,但是rear已经出界)
循环队列:解决假溢出的问题。
队列这种头尾相接的顺序存储结构叫做循环队列。
空队列:front=rear
队列满:
(1)设置标志变量进行判断
flag=0时,front==rear;
flag=1时,front==rear
(2)队列空时,front=rear;
队列满时,保留一个空闲单元,
(rear+1)%QueueSize ==front;
循环队列,可能产生数组溢出的现象。可以看看链式存储。
2.4队列的链式存储
队头指针指向链队列的头结点,队尾指针指向终端结点。