栈是一个特殊的线性表,只能在一端操作;
栈顶(top):允许操作 的一端;
栈底(bottom):不允许操作的一端
性质:先进后出

栈的常见操作:
创建栈
销毁栈
清空栈
进栈
出栈
获取栈顶元素
获取栈的长度

1.栈:是限定仅在表尾进行插入和删除操作的线性表;又称后进先出的线性表。LIFO结构。
     栈顶top:允许插入和删除的一端;
     栈底bottom:另外一端;

2. 空栈:不含任何数据元素的栈;top=-1;

3. 栈的操作:
   进栈,压栈,入栈:栈的插入操作;
   出栈,弹栈:栈的删除操作;
   栈中有一个元素时,top=0;
4. 栈的抽象数据类型:
  插入和删除:push,pop  同线性表。  元素具有相同的类型,相邻元素具有前驱和后继的的关系。
  操作:
  a.初始化操作,建立空栈S;
  b. 若栈存在,就销毁它;
  c.将栈清空;
  d.判断栈是否空:空返回true,否则返回false;
  e. 若栈存在非空,用e返回s的栈顶元素;
  f. 若栈S存在,插入新元素e到栈s成为栈顶元素;
  g.删除栈s栈顶元素,并用e返回其值;
  h.返回栈s的元素个数。

5. 若存储栈的长度为StackSize,则栈顶位置top必须小于StackSize。
  若栈存在一个元素,top=0;
  空栈的条件:top=-1;

   栈的结构:

typedef  struct sqStack
{
      int data[MAXSIZE];
      int top;
}STACK;

6.进栈操作:

  int Push(STACK *S, int e)
  {
       if(S->top == MAXSIZE -1)
         return error;
       S->top++;
       S->data[S->top]=e;
        return OK; 
  }

7. 出栈操作:

  int Pop(STACK *S, int *e)
  {
    if(S->top == -1)
     return ERROR;
    *e=S->data[S->top];
    S->top--;
    return OK;
 }

 

8.栈的链式存储结构
  栈的链式存储结构,简称为链栈;
  栈顶放在单链表的头部;
  链栈是不需要头结点的。
  链栈不存在栈满的情况。

进栈出栈
1.进栈操作:元素值为e的新节点s,top为栈顶指针;

   int Push(LinkStack *S, int e)
  {
     LinkStackPtr p= (LinkStackPtr) malloc (sizeof(StackNode));
     p->data=e;
     p->next=S->top;
     S->top=p;
     S->count++;
     return OK;
  }


2.栈的链式出栈:
pop操作:用变量p用来存储要删除的栈顶结点,将栈顶指针向下移动一位,最后释放p即可。

   int Pop(LinkStack *S, int *e)
  {
     LinkStackPtr  p;
     if(StackEmpty(*S))
       return ERROR;
     *e=S->top->data;
     p=S->top;
     S->top=S->top->next;
     free(p);
     S->count--;
     reuturn OK;
  }

 

队列
队列是特殊的线性表;
队列仅在线性表两端进行操作;
队头(Front):取出数据的一端;
队尾(Rear):放入数据的一端;
性质:先进先出。

常见队列的操作:
创建队列
销毁队列
清空队列
进队列
出队列
获取队头元素
获取队列长度

a.队列的抽象数据模型:
   1)初始化操作,建立一个空队列Q;
   2)若队列存在,则销毁它;
   3)将队列清空
   4)若队列Q为空,返回true,否则返回false;
   5)若队列Q存在且非空,用e返回队列Q的队头元素;
   6)若队列Q存在,插入新元素e到队列Q中,并成功称为队尾元素;
   7)删除队列Q中队头元素,并用e返回其值;
   8)返回队列Q的元素个数;
 

b.循环队列:
1.队列顺序存储的不足:
   避免出现只有一个元素时,队头和队尾的重合处理麻烦,
   引入front指向队头元素,rear指向队尾元素的下一个位置;
   front=rear时,队列不是还剩一个元素,而是空队列;

2.循环队列定义:
   把头尾相接的顺序存储结构称为循环队列;
   判断队列满的条件:
   (rear+1)%QueueSize==front;
   通用的计算队列长度公式为:
   (rear-front+QueueSize)%QueueSize;

typedef  struct 
{
      int data[MAXSIZE];
      int front;
      int rear;
}SqQueue;

 

3.初始化一个空队列Q:

   int InitQueue(SqQueue *Q)
   {
     Q->front = 0;
     Q->rear  = 0;
     return OK; 
   }

 

4.求队列长度:

   int  QueueLength(SqQueue  Q)
   {
       return (Q.rear -Q.front+MAXSIZE)%MAXSIZE;
   }

 

5 . 循环队列的入队列:

   int EnQueue(SqQueue *Q, int e)
   {
        if((Q->rear+1)%MAXSIZE ==Q->front)
            return ERROR;
        Q->data[Q->rear] = e;
        Q->rear=(Q->rear+1)%MAXSIZE;
        return OK;
   }

 

6.循环队列的出队列:

   int DeQueue(SqQueue *Q, int *e)
   {
       if(Q->rear==Q->front)
         return ERROR;
       *e=Q->data[Q->front];
       Q->front=(Q->front+1)%MAXSIZE;
       return OK;
   }