zoukankan      html  css  js  c++  java
  • 栈与队列

    一、栈

    (一)、定义

    顺序栈(main)

    1. 定义

      #define MaxSize 50
      
      typedef struct{
          ElementType data[MaxSize];
          int top;
      }SqStack;
      

    共享栈

    1. 定义:定义一个数组,选择某个位置作为栈底,两边向内生长

    栈的链式存储结构

    1. 定义:

      typedef struct Linknode{
          ElementType data;
          struct Linknode *next;
      }*LiStack;
      

    (二)、操作

    初始化

    1. 功能:初始化栈

    2. code

      void initStack(SqStack &s){
          s.top=-1;
      }
      

    判栈空

    1. 功能:判断栈是否为空

    2. code

      bool stackEmpty(SqStack s){
          if(s.top!=-1){
              return false;
          }else{
              return true;
          }
      }
      

    进栈

    1. 功能:进栈

    2. code

      bool push(SqStack &s,ElementType e){
          if(s.top==MaxSize){  //判断栈满
              return false;
          }
          s.data[++s.top]=e;
          return true;
      }
      

    出栈

    1. 功能:出栈

    2. code

      bool pop(SqStack &s,ElementType &e){
          if(s.top==-1){  //判断栈空
              return false;
          }
          e=s.data[s.top--];
          return true;
      }
      

    读栈顶元素

    1. 功能:获取栈顶元素

    2. code

      bool getTop(SqStack s,ElementType &e){
          if(s.top==-1){
              return false;
          }
          e=s.data[s.top];
          return true;
      }
      

    二、队列

    (一)、定义

    顺序队列

    1. 定义

      typedef struct{
          ElementType data[MaxSize];
          int front,rear;
      }SqQueue;
      
    2. 特点:

      • 队空:Q.front=Q.rear
      • 队满:无法使用Q.rear==MaxSize

    循环队列(main)

    1. 定义

      typedef struct{
          ElementType data[MaxSize];
          int front,rear;
      }SqQueue;
      
    2. 特点:

      • 队空:Q.front==NULL&&Q.rear!=NULL
      • 队满:Q.front==NULL&&Q.rear!=NULL
    3. 由于队空队满条件相同的三种处理:

      • 牺牲一个队列单元来区分队空还是队满

        • 队满:(Q.rear+1)%MaxSize=Q.front
        • 队空:Q.front==Q.rear
      • 类型中增加表示元素个数的数据成员

      • 类型中设置tag数据成员

        思想:通过多设置一个tag来区分不同状态下的队满或队空条件

        • tag=0,若因删除导致Q.front==Q.rear,则为队空
        • tag=1,若因插入导致Q.front==Q.rear,则为队满

    链式存储

    1. 定义

      typedef struct{
          ElementType data;
          struct LinkNode *next;
      }LinkNode;
      typedef struct{
          LinkNOde *front,*rear;
      }LinkQueue;
      
    2. 特点:

      • 队空:Q.front==NULL&&Q.rear==NULL
      • 队满:无
    3. 注:

      • 建议带头结点
      • LinkQueue中实际只有front和rear两个节点

    (二)、操作

    循环队列

    初始化

    1. 功能:初始化

    2. code

      void initQueue(SqQueue &q){
          q.front=0;
          q.rear=0;
      }
      

    判队空

    1. 功能:判队空

    2. code

      bool isEmpty(SqQueue Q){
          if(q.front==q.rear) return true;
          else return false;
      }
      
    3. 注意:循环队列下判空条件依然为q.front==q.rear

    入队

    1. 功能:入队

    2. code

      bool EnQueue(SqQueue &q,ElementType x){
          if((q.rear+1)%MaxSize==q.front) return false;  //验满
          q.rear=(q.rear+1)%MaxSize;
          q.data[q.rear]=x;
          return true;
      }
      

    出队

    1. 功能:出队

    2. code

      bool deQueue(SqQueue &q,ElementType &x){
          if(q.rear==q.front) return false;  //验空
          x=q.data[q.front];
          q.front=(q.front+1)%MaxSize;
      }
      

    链式存储

    初始化

    1. 定义:初始化

    2. code

      void initQueue(LinkQueue &q){
          q->front=q->rear=(LinkNode *)malloc(sizeof(LinkNOde));
          q.front.next=NULL;  //设置首节点的next为NULL
      }
      
    3. 注:链式存储下的q中实际只有frontrear两个结点

    判队空

    1. 定义:判队空

    2. code

      void isEmpty(LinkQueue Q){
          if(q.front==q.rear)  return true;
          else return false;
      }
      

    入队

    1. 定义:入队

    2. code

      void enQueue(LinkQueue &q,ElementType x){
          //不用判队空
          LinkNode *temp=(LinkNode *)malloc(sizeof(LinkNode));
          temp->data=x;
          temp->next=NULL;
          q.rear->next=temp;
          q.rear=q.rear->next;
      }
      

    出队

    1. 定义:出队

    2. code

      bool deQueue(LinkQueue &q,ElementType &x){
          //判空
          if(q.rear==q.front) return false;
          LinkNode *temp=q.front->next;
          x=temp->data;
          q.front=q.front->next;
          if(q.rear==temp){
              return true;  //保持一个节点,最后一个不释放
          }
          free(temp);
          return true;
      }
      

    三、应用

    (一)、中缀表达式转后缀

    1. 规则

      • 如果遇到普通的数输出
      • 遇到(,直接入栈
      • 遇到),将运算符弹出栈直到遇到)
      • 遇到一般运算符s,根据运算符的优先级:匹配栈顶的运算符t,出栈直到遇到优先级比s低的运算符
    2. code

      #include <stdio.h>
      #include <stdlib.h>
      #include <iostream>
      #include <algorithm>
      #include <cstring>
      #include <stack>
      #include <map>
      
      using namespace std;
      
      stack<char> s;
      map<char,int> mp;
      
      void init(){
          //初始化map,定义运算符号优先级
          mp['*']=2;
          mp['/']=2;
          mp['+']=1;
          mp['-']=1;
      }
      
      string toSuffixExpression(string str){
          int len=str.length();
          string ans="";
          for(int i=0;i<len;i++){
              if(str[i]<='9'&&str[i]>='0'){
                  ans+=str[i];  //对于数值直接输出,因为对于中缀转后缀数字的相对位置不变
                  //cout << "num:" << str[i] << endl;
              }
              else if(str[i]=='('){
                  s.push(str[i]);
              }
              else if(str[i]==')'){
                  while(s.top()!='('){
                      ans += s.top();
                      s.pop();
                  }
                  s.pop();
              }
              else{
                  while(s.size()!=0&&mp[str[i]]<=mp[s.top()]){
                      //cout << "str:" << str[i] << endl;
                      //cout << "pop:" << s.top() << endl;
                      ans += s.top();
                      s.pop();
                  }
                  s.push(str[i]);
              }
          }
          while(s.size()!=0){  //如果栈内还有运算符,追加到式子后面
              ans+=s.top();
              s.pop();
          }
          return ans;
      }
      
      int main(){
          init();
          string str;
          cin >> str;
          cout << toSuffixExpression(str);
      }
      
    3. 注:无法将(使用运算符的优先级进行操作

      • (直接入栈,所以必然是优先级最低的运算符
      • )必须匹配到(,如果将)设置为最低优先级的运算符,则每次遇到)必然会将栈中所有运算符都弹出
  • 相关阅读:
    JavaScriptCore框架介绍
    可执行程序加载到内存的过程
    阿里云服务器怎么更换系统盘
    什么是A记录  域名
    宝塔服务器管理助手Linux面版-使用教程
    虚拟主机、VPS以及云主机的区别和对比
    怎样选择一个好的虚拟主机
    解Linux SSH命令大全,新手必看SSH命令
    虚拟主机,VPS,云主机之间的区别?
    云服务器和虚拟主机的区别:
  • 原文地址:https://www.cnblogs.com/Arno-vc/p/14998012.html
Copyright © 2011-2022 走看看