栈与队列的应用实例 出栈顺序
条件: 进栈时允许出栈
解题思路: 向上进行时可以跳跃,向下进行时不可以出现跳跃
Ex:1 某栈的输入序列为a,b,c,d,下面的四个序列中,不可能为其输出序列的是() A.a,b,c,d B.c,b,d,a C.d,c,a,b D.a,c,b,d
进制转换:倒取n/d的余数(d为进制数) EX:2:取 135的二进制数(完整实现)
括号匹配的检验 依次压入所求括号,遇到右括号便进行出栈操作两次,如果两括号匹配则继续进行入栈和遇到右括号便出栈两次的操作,如果不匹配则退出循环返回括号不匹配 顺序栈的初始化、判空、清空、求长、销毁 顺序栈的表示 1 2 3 4 5 6 #define max_Size 100 typedef struct SqStack { ElemType* base; ElemType* top; int stacksize; }SqStack;
顺序栈的初始化 1 2 3 4 5 6 int InitStack (SqStack &S) { S.base = (ElemType *)malloc (sizeof (ElemType)*max_Size); if (!S.base) return 0 ; S.top = S.base; return 1 ; }
顺序栈的判空 1 2 3 4 int StackEmpty (SqStack &S) { if (S.top==S.base) return 1 ; else return 0 ; }
清空顺序栈 1 2 3 4 int ClearStack (SqStack &S) { if (S.base) S.top = S.base; return 1 ; }
求顺序栈长度 1 2 3 4 5 int StackLength (SqStack S) { return 1 ; return S.top - S.base; }
销毁顺序栈 1 2 3 4 5 6 7 8 int DestroyStack (SqStack &S) { if (S.base){ free (S.base); S.stacksize = 0 ; S.top = S.base = NULL ; } }
顺序栈的入栈与出栈 入栈 1 2 3 4 5 6 int Push (SqStack &S,ElemType e) { if (S.top - S.base == S.stacksize) return 0 ; *S.top = e; S.top++; return 1 ; }
出栈 1 2 3 4 5 6 int Pop (SqStack &S,ElemType &e) { if (S.top == S.base) return 0 ; S.top--; e = *S.top; return 1 ; }
应用:十进制转换二进制数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream> #include <cstdlib> using namespace std;#define max_Size 100 typedef struct SqStack { int * top = NULL ; int * base = NULL ; int stacksize = max_Size; }SqStack; int Push (SqStack &S,int e) { if (S.top - S.base == S.stacksize) return 0 ; *S.top = e; S.top++; return 1 ; } int Pop (SqStack &S) { if (S.top == S.base) return 0 ; S.top--; int t = *S.top; return t; } int main () { SqStack S; S.base = (int *)malloc (sizeof (int )*max_Size); S.top = S.base; int x; cin >> x; while (x>0 ){ int t = x%2 ; Push (S,x%2 ); x = (x - t)/2 ; } while (S.top != S.base) cout << Pop (S); }
链栈的初始化、判空 链栈的初始化 1 2 3 void InitStack (LinkStack &S) { S = NULL ; }
节点定义
1 2 3 4 typedef struct StackNode { Elemtype data; StackNode* next; }StackNode,*LinkStack;
链栈的判空 1 2 3 4 int StackEmpty (LinkStack &S) { if (S == NULL ) return 1 ; else return 0 ; }
链栈的出入栈操作 与普通链表不同,链栈是一个不带头结点的链表,链栈指针S指向的是链表末尾元素(因为链表后进先出的特性) 如图所示:
链栈的入栈 1 2 3 4 5 6 7 int push (LinkStack &S,Elemtype e) { StackNode* p = (StackNode *)malloc (sizeof (StackNode)); p -> data = e; p -> next = S; S = p; return 1 ; }
链栈的出栈 1 2 3 4 5 6 7 8 int pop (LinkStack &S,Elemtype &e) { if (S==NULL ) return 0 ; e = S -> data; StackNode* p = S; S = S -> next; free (p); return 1 ; }
队列的真溢出、假溢出 真溢出:front==0;rear==max_Size 假溢出:front!=0;rear==max_Size 由于假溢出的存在,大部分队列使用的是顺序循环结构
队列的表示、入队、出队 队列的表示 1 2 3 4 5 typedef struct SqQueue { ElemType* base; int front; int rear; }
队列的入队 1 2 Q.base[Q.rear] = x; Q.rear = (Q.rear + 1 ) % max_Size;
队列的出队 1 2 x = Q.base[Q.front]; Q.front = (Q.front + 1 ) % max_Size;
注意:
循环队列并非是一个真正的循环结构,而是通过取余(%)运算来实现循环。
循环队列无法判断队空、队满,二者条件均为rear==front,如图所示:
解决方案:
另外设一个标志以区别队空队满
另设一个变量记录元素个数
少用一个元素空间
基于少用一个空间的区分循环队列队满队空的方法 1 2 (Q.rear + 1 ) % max_Size = Q.front; Q.rear == Q.front;
队列的初始化、求长 队列的初始化 1 2 3 4 5 6 int InitQueue (SqQueue &Q) { Q.base = (ElemType *)malloc (sizeof (ElemType) * max_Size); if (!Q.base) return 0 ; Q.front = Q.rear = 0 ; return 1 ; }
队列求长 1 2 3 int QueueLength (SqQueue Q) { return (Q.rear-Q.front + max_Size) % max_Size; }
队列的入队、出队 队列的入队 1 2 3 4 5 int EnQueue (SqQueue &Q,ElemType e) { if ((Q.rear + 1 ) % max_Size == Q.front) return 0 ; Q.base[Q.rear] = e; Q.rear = (Q.rear + 1 ) % max_Size; }
队列的出队 1 2 3 4 5 int DeQueue (SqQueue &Q,ElemType &e) { if (Q.rear == Q.front) return 0 ; e = Q.base[Q.front]; Q.front = (Q.front + 1 ) % max_Size; }
链队列相关操作 链队列定义 1 2 3 4 5 6 7 8 typedef struct QNode { ElemType data; Qnode* next; }QNode,*QueuePtr; typedef struct LinkQueue { QNode* front; QNode* rear; }LinkQueue;
链队列初始化 1 2 3 4 5 int InitQueue (LinkQueue &Q) { Q.rear = Q.front = (QNode *)mallco (sizeof (QNode)); Q.front -> next = NULL ; return 1 ; }
链队列销毁 1 2 3 4 5 6 7 8 9 int DestroyQueue (LinkQueue &Q) { while (Q.front!= NULL ){ QNode* p = Q.front; Q.front = Q.front -> next; free (p); } Q.rear = NULL ; return 1 ; }
链队列入队 1 2 3 4 5 6 7 int EnQueue (LinkQueue &Q,ElemType e) { QNode* p = (QNode *)mallco (sizeof (QNode)); p -> data = e; p -> next = NULL ; Q.rear -> next = p; Q.rear = p; }
链队列出队 1 2 3 4 5 6 7 8 9 int EnQueue (LinkQueue &Q,ElemType &e) { if (Q.rear = Q.front) return 0 ; QNode* p = Q.front -> next; e = p -> data; Q.front -> next = p -> next; if (Q.rear == p) Q.rear = Q.front; free (p); }