第三章 栈与队列
一、栈
1.栈:只能在表尾进行插入和删除操作的线性表
允许插入和删除的一端称为栈顶,另一端为栈底
2.栈的操作特性:线性关系;后进先出
3.顺序栈:是栈的顺序存储结构,是顺序表的简化
栈底—>数组下标为0的一端
top指针—>栈顶元素在数组中的位置
4.顺序栈的栈空和栈满条件
栈空:top=-1 栈满:top=StackSize-1
5.顺序栈的进栈和出栈操作
进栈:data[++top]=x;
出栈:return data[top--];
时间复杂度:均为O(1)
6.两栈共享空间:一个数组存储两个栈,一个栈的栈底为数组的始端,另一个栈的栈底为数组的末端,向中间共同延伸
7.两栈共享空间的进栈和出栈操作
进栈:if(i==1)data[++top1]=x;
if(i==2)data[--top2]=x;
出栈:if(i==1)return data[top1--];
if(i==2)return data[top2++];
时间复杂度:均为O(1)
8.链栈:栈的链接存储结构,用单链表实现,但不用附设头结点
9.链栈的栈空和栈满条件
栈空:top==NULL 栈满:内存无可用空间时
10.链栈的进栈和出栈操作
进栈:s->next=top;top=s;
出栈:x=top->data;p=top;top=top->next;
delete p;return x;
时间复杂度:均为O(1)
11.顺序栈和链栈的比较
(1)相同:所有基本操作算法都只需常数时间
(2)不同:空间性能的不同
i.顺序栈有存储元素个数限制和空间浪费的问题,可共享空间
ii.链栈一般没有栈满问题,但指针域造成了结构性开销
二、队列
1.队列:只允许在一端进行插入操作,另一端进行删除操作的线性表
允许插入的一端称为队尾,允许删除的一端称为队头
2.队列的操作特性:线性关系;先进先出
3.循环队列:为了解决顺序队列可能出现的“假溢出”问题,采用这种队列的首尾相接的顺序存储结构,称为循环队列
队头指针front ——>队头元素的前一个位置
队尾指针rear ——>队尾元素
队列长度:QueueSize=(rear-front+n)%n n为数组的长度
在循环队列中,凡是涉及到队头或队尾指针的修改都需要将其求模
4.循环队列的队空和队满条件
队空:front=rear
队满(浪费一个存储单元):(rear+1)%QueueSize=front
5.循环队列的入队和出队操作
入队:rear=(rear+1)%QueueSize;data[rear]=x;
出队:front=(front+1)%QueueSize;return data[front]
时间复杂度:均为O(1)
6.链队列:队列的链接存储结构,用单链表实现,需要附设头结点,
队头指针—>头结点,队尾指针—>终端结点
7.链队列的队空和队满条件
队空:front=rear 队满:内存无可用空间时
8.链队列的入队和出队操作
入队:rear->next=s;rear=s;
出队:必须要考虑队列长度为1的情况
p=front->next;x=p->data;front->next=p->next;
if(p>next==NULL)rear=front;
delete p;return x;
时间复杂度:均为O(1)
9.循环队列和链队列的比较
(1)相同:所有基本操作算法都只需常数时间
(2)不同:空间性能的不同
i.循环队列有存储元素个数限制和空间浪费的问题,但不能在一个数组中存储两个循环队列
ii.链队列一般没有队满问题,但指针域造成了结构性开销
三、栈与队列的比较
1.相同点:都是特殊的线性表
2.不同点:操作特性不同,栈后进先出,队列先进先出
3.主要区别:对插入和删除操作限定的位置不同
四、栈的应用:中缀表达式转换成后缀表达式
1.将临时栈S初始化为空栈,用来暂存运算符
2.从左到右依次扫描表达式的每一个字符,执行下述操作:
2.1 若当前字符是运算对象,输出该字符,处理下一个字符
2.2 若当前字符是运算符,比较该运算符与栈顶运算符的优先级
2.2.1 若高,该字符进栈,处理下一个字符
2.2.2 若等,栈顶元素弹出,处理下一个字符
2.2.3 若低,栈顶元素弹出,并输出该栈顶元素,接着处理该字符
补充:#为中缀表达式的定界符,优先级从高到底排列:
( )、*、/、+、-、# ,且括号中的运算符优先级比括号高
例:将中缀表达式3*(4+2)/2-5转化成后缀表达式为:342 + * 2/5 -
详细过程如下: