# 原创 : 第三章 栈和队列 # 第三章 栈和队列 ## 一、基本概念 栈:先进先出,顺序栈和链式栈,本质上是线性表
队列:先进后出,一种操作受限的线性表 ## 二、结构体定义 ``` //1.顺序栈定义 typedef struct { int date[maxSize]; int top; }SqStack; //2.链栈结点定义 typedef struct LNode { int date; struct LNode *next; }LNode; //3.顺序队列定义 typedef struct { int date[maxSize]; int front; int rear; }SqQueue; //4.链队定义 //队结点类型定义 typedef struct QNode { int date; struct QNode *next; }QNode; //链队类型定义 typedef struct { QNode *front; QNode *rear; }LiNode; ``` ## 三、顺序栈 ``` //1.顺序栈要素 st.top==-1; //栈空 st.top==maxSize-1; //栈满 //还有一种就是上溢和下溢 //2.两个操作 st.date[++(st.top)]=x; //进栈 x=st.date[(st.top)--]; //出栈 //3.初始化栈 void initStack(SqStack &st) { st.top=-1; } //4.判断栈空 int isEmpty(SqStack st) { if(st.top==-1)return -1; else return 0; } //5.进栈 int push(SqStack &st, int x) { if(st.top==maxSize-1)return 0; st.date[++(st.top)]=x; return 1; } //6.出栈 int pop(SqStack &st, int &x) { if(st.top==-1)return 0; x=st.date[st.top--]; return 1; } //比较实用的写法 int stack[maxSize];int top=-1; stack[++top]=x; x=stack[top--]; ``` ## 四、链栈 ``` //1.要素 //两个状态 lst->next==NULL; //栈空 //栈满,除非内存耗尽 //两个操作 p->next=lst->next;lst->next=p; //进栈 p=lst->next;x=p->date;lst->next=p->next;free(p);//出栈 //2.链栈的初始化代码 void initStack(LNode *&lst)\ { lst=(LNode*)malloc(sizeof(LNode)); lst->next=NULL; } //3.判断栈空代码 int isEmpty(LNode *lst) { if(lst->next==NULL)return 1; else return 0; } //4.进栈 void push(LNode *lst, int x) { LNode *p; p=(LNode)malloc(sizeof(LNode)); p->next=NULL; p->date=x; p->next=lst->next; lst->next=p; } //5.出栈 void pop(LNode *lst, int *&x) { LNode *p; if(lst->next==NULL)return 0; p=lst->next; x=p->date; lst->next=lst->next->next; free(p); return 1; } ``` ## 五、栈的应用 ``` //1.算法:判断一个表达式的括号是否配对 int match(char exp[], int n) { char stack[maxSize];int top=-1; //顺序栈的定义和初始化 int i; for(i=0;i<n;++i) { if(exp[i]=='(')stack[++top]='('; if(exp[i]==')') { if(top==-1)return 0; else top--; } } if(top==-1) return 1; else return 0; } //2.算法:求后缀式表达式数值 //中缀式:(a+b+c*d)/e; //前缀式:/++ab*cde; //后缀式:abcd*++e/ int op(int a, char Op, int b) { if(Op=='+')return a+b; if(Op=='-')return a-b; if(Op=='*')return a*b; if(Op=='/') { if(b==0) { cout<<"ERROR"; return 0; } else return a/b; } } int com(char exp[]) { int i,a,b,c; //其中a,b为操作数,c保存结果 int stack[maxSize];int top=-1; char Op; for(i=0;exp[i]!='\0';++i) { //注意字符型和整型的转换 if(exp[i]>='0'&&exp[i]<='9')stack[++top]=exp[i]-'0'; else { Op=exp[i]; b=stack[top--];//先取第二个操作数 a=stack[top--]; c=op(a,Op,b); stack[++top]=c; } } return stack[top]; } //3.不带头结点的单链表存储链栈 void initStack(LNode *&lst) { lst==NULL; } int isEmpltyl(LNode *lst) { if(lst==NUll)return 1; else return 0; } void push(LNode *&lst, int x) { LNodde *p; p=(LNode*)malloc(sizeof(LNode)); p->next=NULL; p->date=x; //lst不带头结点 p->next=lst->next; lst=p; } int pop(LNode *&lst, int &x) { LNode *p; if(lst==NULL)return 0; p=lst; x=p->date; lst=p->next; free(p); return 1; } ``` ## 六、顺序队 ``` //1.四个要素 qu.rear==qu.front; //队空 (qu.rear+1)%maxSize==qu.front; //队满 qu.rear=(qu.rear+1)%maxSize;qu.date[qu.rear]=x; //进队,移动队尾指针 qu.front=(qu.rear+1)%maxSize;x=qu.date[qu.front]; //出队,移动队首指针 //2.初始化队列 void initStack(SqQueue qu) { qu.front=qu.rear=0 } //3.判断队空 int isQueueEmpty(SqQueue qu) { if(qu.rear==qu.front)return 1; else return 0; } //4.进队 int enQueue(SqQueue &qu, int x) { //队满不能进队 if((qu.rear+1)%maxSize==qu.front)return 0; qu.rear=(qu.rear+1)%maxSize; qu.date=x; return 1; } //5.出队 int deQueue(SqQueue &qu, int &x) { if(qu.front==qu.rear)return 0; qu.front=(qu.front+1)%maxSize; x=qu.date[qu.front]; return 1; } ``` ## 七、链队 ``` //1.要素 lqu->rear==NULL||lqu->front==NULL; //队空 //不存在队满 lqu->rear->next=p;lqu->rear=p; //进队 p=lqu->front;lqu->front=p->next;x=p->date;free(p); //出队 //2.初始化链队 void initQueue(LiQueue *&lqu) { lqu=(LiQueue*)malloc(sizeof(LiQueue)); lqu->front=lqu->rear=NULL; } //3.判断队空 init isQueueEmpty(LiQueue *lqu) { if(lqu->rear==NULL||lqu->front==NULL)return 1; else return 0; } //4.入队 void enQueue(LiQueue *lqu, int x) { QNode *p; p=(QNode*)malloc(sizeof(QNode)); p->date=x; p->next=NULL; if(lqu->rear==NULL)lqu->front=lqu->rear=p; else { lqu->rear->next=p; lqu->rear=p; } } //5.出队 int deQueue(LiQueue *lqu, int &x) { QNode *p; if(lqu->rear==NULL)return 0; else p=lqu->front; if(lqu->front==lqu->rear)lqu->front=lqu->rear=NULL; else lqu->front=lqu->front->next; x=p->date; free(p); return 1; } ``` ## 八、实例 ``` //1.共享栈s0、s1的相关操作,共享elem[0,1,...,maxSize-1] //结构体定义 typedef struct { int elem[maxSize]; int top[2]; }SqStack; //入栈 int push(SqStack &st, int stNo, int x) { if(st.top[0]+1<st.top[1]) { if(stNo==0) { ++(st.top[0]); st.elem[st.top[0]]=x; return 1; } else if(stNo==1) { --(st.top[1]); st.elem[st.top[1]]=x; return 1; } else return -1; } else return 0; } //出栈 int pop(SqStack &st, int dtNo, int &x) { if(stNo==0) { if(st.top[0]!=-1) { x=st.elem[st.top[0]]; --(st.top[0]); return 1; } else return 0; } else if(stNo==1) { if(st.top[1]!=maxSize) { x=st.elem[st.top]; ++(st.top[1]); return 1; } else return 0; } else return -1; } //2.用两个栈s1和s2模拟一个队列 //入栈 int enQueue(SqStack &s1,SqStack &s2,int x) { int y; if(s1.top==maxSize-1) { if(!isEmpty(s2))return 0; else if(isEmpty(s2)) { while(!siEmpty(s1)) { //s1中元素出栈,进入s2中 pop(s1,y); push(s2,y); } push(s1,x); return 1; } } else { push(s1,x); return 1; } } //s2退栈,实现出队 int deQueue(SqStack &s2, SqStack &s1, int &x) { int y; if(!isEmpty(s2)) { pop(s2,x); return 1; } else { if(isEmpty(s1))return 0; else { while(!isEmpty(s1)) { pop(s1,y); push(s2,y); } pop(s2,x); return 1; } } } //判断栈s1和s2模拟的队列是否为空 int isQueueEmpty(SqStack s1,SqStack s2) { if(isEmpty(s1)&&isEmpty(s2))return 1; else return 0; } ```