栈和队列

定义

:是限定仅在表尾进行插入或者删除操作的线性表、可以概括为后进先出的线性表。
栈顶:线性表允许进行插入和删除操作的那一端。
栈底:固定的、不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。

栈的顺序存储结构

类似于顺序表、插入和删除操作均在表尾。

栈的顺序存储的表示
    typedef struct {
       Elemtype *base,*top;
       int stacksize;
       }SqStack;
顺序栈的基本操作
    #define MaxSize 50;
    type struct{
     Elemtype data[MaxSize];
     int top;
     }SqStack;
初始化
  void InitStack(&S){
   S.top=-1;
   }
栈判空
  bool StackEmpty(S){
   return S.top==-1;
   }
进栈
   bool Push(SqStack &S,ElemType x){
    if(S.top==MaxSize-1)
        return false;
     S.data[++S.top]=x;
        return true;   
   }
出栈
   bool Pop(SqStack&S,ElemType &x){
     if(S.top==-1)
       return false;
     x=S.data[S.top--]; //先出栈在--
     return true;  
   } 
栈顶元素
   bool GetTop(SqStack S,ElemType &x)
   {
   if(S.top==-1)
      return false;
   x=S.data[S.top];
      return true;
  //注意: 这里栈顶指针指向的就是栈顶元素、如果栈顶指针初始化为S.top=0,则入栈变为S.data[S.top++],出栈变为x=S.data[--S.top]         
栈的链式存储结构

通常用不带头结点的单链表实现、并规定所有操作都在表头进行。

栈的链式存储表示
   typedef struct Linknode{
      Elemtype data;
      struct Linknode *next;
      }*LiStack;
链栈的基本操作
入栈
   bool Push(LiStack &s,ElemType x)
   {
   Linknode *p;  //申明入栈结点
   p=(Linknode)malloc(sizeof(Linknode)); //申请空间
   if(!p)
     return false;
   p->data=x;
   p->next=s;  //指向栈
   s=p;   //重新指向栈顶
   return true;
出栈
   bool Pop(LiStack &s,ElemType &x)
   {
      Linknode *p;
      if(!s)
      return false;
      p=s;
      s=s->next; //栈顶指向下一个栈元素
      x=p->data;
      free(p);
      return true;
   }
栈顶元素
   bool GetTop(LiStack &s,ElemType &x)
   {
       if(s)
       return false;
       x=s->data;
       return true;
    }  
队列
定义

队列:一种操作受限的线性表、只允许在表的一端进行插入、而在表的另一端进行删除。其操作特性是先进先出、故又称先进先出的线性表。
队头:允许删除的一端、又称为队首。
队尾:允许插入的一端。
空队列:不含任何元素的空表。

队列的顺序存储

队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针front和rear分别指向队头元素和队尾元素的位置。

队列的顺序存储表示
  #define MaxSize 50
  typedef struct{
    ElemType data[MaxSize];
    int front,rear;
   }SqQueue;
 //设front指向队头元素、rear指向对尾元素的下一个位置、则
 //队空条件为:Q.front==Q.rear==0;
 //入队操作:队不满时,先送值到队尾元素、再将队尾指针加1;
 //出队操作:队不空时,先去队头元素值,再将队头指针加1;
 //能否用Q.rear==MaxSize判断队满?不能、因此引出循环队列
循环队列

将顺序队列想象成一个环状的存储空间、即把存储队列元素的表从逻辑上看成一个环、称为循环队列。当队首指针Q.front==MaxSize-1,在前进一个位置就自动到0,则

  1. 队空条件:Q.front==Q.rear;
  2. 队满条件:(Q.rear+1)%MaxSize==Q.front (队列少用一个元素时);
  3. 进队操作:Q.rear=(Q.rear+1)%MaxSize;
  4. 出队操作:Q.front=(Q.front+1)%MaxSize;
  5. 队列长度:(Q.rear+MaxSize-Q.front)%MaxSize;
初始化
  void InitQueue(&Q){
     Q.front=Q.rear=0;
  }
入队操作
   bool EnQueue(SqQueue &Q,ElemType x){
     if((Q.rear+1)%MaxSize==Q.front)
            return false; //队列满
      Q.data[Q.rear]=x;  //数组从0开始
      Q.rear=(Q.rear+1)%MaxSize;
      return true;      
   }
出队操作
  bool DeQueue(SqQueue &Q,ElemType &x){
  if(Q.front==Q.rear)
      return false;
  x=Q.data[Q.front];
  Q.front=(Q.front+1)%MaxSize;
  return true;    
队列中的 元素个数
  int QueueLength(SqQueue Q){
      return (Q.rear-Q.front+MaxSize)%MaxSize;
  }
队列的链式存储结构

队列的链式实现称为链队列,即一个同时带有队头指针和对尾指针的单链表,头指针指向队头结点,尾指针指向队尾结点(单链表的最后一个结点)。

队列的链式存储
  typedef struct QNode{
      QElemtype data;
      struct QNode *next;
    }QNode,*QueuePtr;
  typedef struct{
      QueuePtr *front,*rear;
    }LinkQueue;  
初始化
  Status InitQueue(LinkQueue &Q){
  //构造一个空队列
  Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
  if(!Q.front) exit(OVERFLOW);
  Q.front->next=null;
  return OK;
队空
  void isEmpty(LinkQueue &Q){
    return Q.front==Q.rear);
    }
入队
  Status EnQueue(LinkQueue &Q,QElemType e){
  //插入元素e为Q的新的队尾元素
    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);
    p->data=e;
    p->next=NUll;
    Q.rear->next=p;
    Q.rear=p;
    return OK;
出队
  Status Deque(LinkQueue &Q,QElemType &e){
	  //若队列不空、则删除Q的队头元素,用e返回其值,并返回OK;
	  //否则返回ERROR
	  if(Q.front==Q.rear) return ERROR;
	  p=Q.front->next;  //头结点front指向的第一个结点
	  e=p->data;
	  Q.front->next=p->next;  //队列往下一个进1
	  if(Q.rear==p) Q.rear=Q.front;
	  free(q);
  return OK;

以上就是对栈和队列的简单梳理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值