8.0 KiB
8.0 KiB
原创
: 第三章 栈和队列
第三章 栈和队列
一、基本概念
栈:先进先出,顺序栈和链式栈,本质上是线性表
队列:先进后出,一种操作受限的线性表
二、结构体定义
//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;
}