栈的特性:后进先出 是限定仅在表尾(栈顶top)插入和删除操作的线性表
出栈次序有限 出栈次序个数为catalan数=[1/(n+1)]*[(n+1)*(n+2)*......(2n)]/[1*2*......n]
空栈判定条件 top==-1
栈的结构定义
typedef int SElemType;
typedef struct
{
SElemType data[MAXSIZE];
int top;
}SqStack;
链栈定义
typedef struct LNode
{
int data;
Struct LNode *next;
} LNode;
入栈代码
Status Push(Sqstack &S, SElemType e)
{
if(S.top==MAXSIZE-1)
return 0;
S.top++;
S.data[S.top]=e;
return 1;
}
出栈代码
Status Pop(Sqstack &S, SElemType &e)
{
if(S.top==-1)
return 0;
e = S.data[S.top];
S.top--;
return 1;
}
简便代码
int stack[maxsize];
int top=-1;
stack[++top]=x;
x=stack[top--];
两栈共享空间
typedef struct
{
SElemType data[MAXSIZE];
int top1;
int top2;
} SqDoubleStack;
共享栈的入栈
Status Push(SqDoubleStack *S, SElemType e, int stackNumber)
{
if(S->top1+1==S->top2)
return 0;
if(stackNumber==1)
S->data[++S->top1]=e;
if(stackNumber==2)
S->data[--S->top2]=e;
return 1;
}
共享栈的出栈
Status Pop(Sqstack *S, SElemType *e, int stackNumber)
{
if(stackNumber==1)
{
if(S->top1==-1)
return 0;
*e = S->data[top1--];
}
if(stackNumber==2)
{
if(S->top2==MAXSIZE)
return 0;
*e = S->data[top2++];
}
return 1;
}
链栈为栈的链式存储结构,没有头结点
链栈初始化
void initStack(LNode *&1st)
{
1st=(LNode *)malloc(sizeof(LNode));
1st->next=NULL;
}
进栈
p->next=1st->next;
1st->next=p;
出栈
p=1st->next;
x=p->data;
1st->next=p->next;
free(p);
如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,最好用链栈
若变化在可控范围内 则用顺序栈
————————————————————————————————————————————
队列是只允许一端进行插入操作,另一端进行删除操作的线性表
特性为先进先出,插入的一端为队尾,删除的一端为队头
顺序队列定义
typedef struct
{
int data[maxsize];
int front;
int rear;
}
链队定义
typedef struct QNode
{
int data;
struct QNode *next;
}QNode;
typedef struct
{
QNode *front;
QNode *rear;
}LiQueue;
假溢出:当队列两个指针front与rear都到达了队列的末端,虽然队列中已经没有元素,但是仍然无法让元素进队。解决方法即使用循环队列
循环队列:队列成环
默认队空条件为rear==front 默认队满条件(rear+1)%size ==front(有一个位置不能存数据,用于区分队空队满)
进队 queue.rear=(queue.rear+1)%maxsize;
queue.data[queue.rear]=x;
出队queue.front=(queue.front+1)%maxsize;
x=queue.data[queue.front];
计算队列长度公式 (rear-front+size)% size
链队队空状态:lqu->rear==NULL;或lqu->front==NULL;
进队lqu->rear->next=p; lqu->rear=p;
出队p=lqu->front; lqu->front=p->next; x=p->data; free(p);
___________________________________________________________
例题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求后缀式数值
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;
int stack[maxsize];
int top==-1;
char Op;
for(int 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];
}