栈的特性:后进先出 是限定仅在表尾(栈顶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];
}