一、栈的应用

栈是一种先进后出(FILO)的数据结构

1.1 栈的操作实现

  1. 清空(clear):

    // 栈的清空操作就是把栈顶top置为-1
    void clear(){top=-1;
    }
    // 清空栈,由于没有直接用于清空栈的元素,所以使用while和pop组合
    while(!st.size()) st.pop();
    
  2. 获取栈内元素个数(size):

    // 由于栈顶指针top始终指向栈顶元素,而下标是从0开始的,所以栈内元素要把top+1
    int size(){return top+1;
    }
    
  3. 判空(empty):

    // 由栈顶指针top判断的定义可知,仅当top==-1是为空,返回true,否则返回false
    bool empty(){if(top==-1) return true; //栈空else return false;  //栈非空
    }
    
  4. 进栈(push):

    // push(x)操作将元素x置于栈顶,由于top始终指向栈顶元素,所以需要把top+1然后再把x存入top位置
    void push(int x){st[++top]=x;
    }
    
  5. 出栈(pop):

    // pop()操作将栈顶元素出栈,而事实上可以将栈顶指针-1来实现这个效果
    void pop(){top--;
    }
    
  6. 取栈顶元素(top):

    // 由于栈顶指针top始终指向栈顶元素,所以st[top]就是栈顶元素
    int top(){return st[top];
    }
    

1.2 STL中stack的常见用法

栈,后进先出(FILO)

  1. stack的定义:

    // 定义一个stack需要添加头文件#include <stack>
    stack<int> st;
    
  2. stack容器内的元素访问:

    // 只能通过top()函数来访问栈顶元素
    st.top();
    
  3. push()函数:

    // push(x)将x入栈
    st.push(1);
    
  4. top()函数:

    // top()函数获得栈顶元素
    st.top();
    
  5. pop()函数:

    // 使用pop()函数弹出栈顶元素
    st.pop();
    
  6. empty()函数:

    // empty()可以检测stack内是否为空,true为空,false为非空
    if(st.enpty()==true)
    
  7. size()函数:

    // 通过size()函数来获得栈的元素个数
    st.size();
    

1.3 使用队列实现栈

class MyStack {
public:/** Initialize your data structure here. */MyStack() {}/** Push element x onto stack. */void push(int x) {queue<int> tempQ;tempQ.push(x);while(!data.empty()) {tempQ.push(data.front());data.pop();}while(!tempQ.empty()){data.push(tempQ.front());tempQ.pop();}}/** Removes the element on top of the stack and returns that element. */int pop() {int ans = data.front();data.pop();return ans;}/** Get the top element. */int top() {return data.front();}/** Returns whether the stack is empty. */bool empty() {return data.empty();}
private:queue<int> data;
};

二、队列

队列是一种先进先出的数据结构,通常用一个队首元素front指向 队首元素的前一个位置, 而使用队尾指针来指向队尾元素。

初始状态(队空条件)∶$Q.front() ==Q.rear()==0 $

进队操作∶队不满时,先送值到队尾元素,再将队尾指针加1

出队操作∶队不空时,先取队头元素值,再将队头指针加1

但 Q.rear()==sizeQ.rear() == sizeQ.rear()==size 不能作为队满的条件。

如下图所示,Q.rear()==sizeQ.rear() == sizeQ.rear()==size 满足前面的条件,但是显然,整个队列还有可以添加的其他元素的(未满)

2.1 队列的操作实现

  1. 清空(clear):

    // 使用数组来实现队列是,初始状态为front=-1,rear=-1
    void clear(){front=rear=-1;
    }
    
  2. 获得队列中的元素个数(size):

    // rear-front是队列内元素的个数
    int size(){return rear-front;
    }
    
  3. 判空(empty):

    // 若rear等于front,则队列为空
    bool empty(){if(front==rear) return true;else return false;
    }
    
  4. 入队(push):

    // 入队,由于指针rear指向队尾元素,因此把元素入队时,需要先把rear+1,在存放到rear指向的位置
    void push(int x){q[++rear]=x;
    }
    
  5. 出队(pop):

    // 直接把队首指针加1来实现出队效果
    void pop(){front++;
    }
    
  6. 取队首元素(get_front):

    // 由于队首指针front指向的队首元素的前一个元素,因此front+1才是队首元素的位置
    int get_front(){return q[front+1];
    }
    
  7. 取队尾元素(get_rear):

    // 由于队尾指针rear指向的队尾元素,因此直接访问rear是队尾元素的位置
    int get_rear(){return q[rear];
    }
    

2.2 STL中queue的常见用法

  1. 判断队列是否为空
Q.empty()
  1. 返回队列头部元素
Q.front()
  1. 返回队列尾部元素
Q.back()
  1. 弹出队列头部元素
Q.pop()
  1. 将x添加至队列
Q.push(x)
  1. 返回队列的存储元素的个数
Q.size()

2.3 使用栈实现队列

class MyQueue {
public:/** Initialize your data structure here. */MyQueue() {}/** Push element x to the back of queue. */void push(int x) {stack<int> tempS;while(!data.empty()) {tempS.push(data.top());data.pop();}tempS.push(x);while(!tempS.empty()){data.push(tempS.top());tempS.pop();}}/** Removes the element from in front of queue and returns that element. */int pop() {int ans = data.top();data.pop();return ans;}/** Get the front element. */int peek() {return data.top();}/** Returns whether the queue is empty. */bool empty() {return data.empty();}
private:stack<int> data;
};

2.4 循环队列

如前面所讲,队列在判断队满的情况下力有不逮,所以就引出了循环队列。

将循环队列想象成一个环状的空间,即在逻辑上视为一个环。

初始时:Q.front==Q.rear==0Q.front==Q.rear==0Q.front==Q.rear==0

队首指针进1:Q.front=(Q.front+1)%MaxSizeQ.front=(Q.front+1)\%MaxSizeQ.front=(Q.front+1)%MaxSize

队尾指针进1:Q.rear=(Q.rear+1)%MaxSizeQ.rear=(Q.rear+1)\%MaxSizeQ.rear=(Q.rear+1)%MaxSize

队列长度:len=(Q.rear+MaxSize−Q.front)%MaxSizelen=(Q.rear+MaxSize-Q.front)\%MaxSizelen=(Q.rear+MaxSize−Q.front)%MaxSize

为了区分队空还是队满的情况,有三种处理方式

  1. 牺牲一个单元来区分队空和队满,入队时少用一个队列单元,这是一种较为普遍的做法,约定以**“队头指针在队尾指针的下一位置作为队满的标志”**,如图下图e所示。

    队满条件:(Q.rear+1)%MaxSize==Q.front(Q.rear+1)\%MaxSize==Q.front(Q.rear+1)%MaxSize==Q.front

    队空条件仍:Q.front==Q.rearQ.front==Q.rearQ.front==Q.rear

    队列中元素的个数:(Q.rear−Q.front+MaxSize)%MaxSize(Q.rear-Q.front+MaxSize)\% MaxSize(Q.rear−Q.front+MaxSize)%MaxSize

  2. 类型中增设表示元素个数的数据成员。这样,队空的条件为 Q.size==0Q.size==0Q.size==0;队满的条件为 Q.size==MaxSizeQ.size==MaxSizeQ.size==MaxSize;这两种情况都有 Q.front==Q.rearQ.front==Q.rearQ.front==Q.rear 。

  3. 类型中增设 tag 数据成员,以区分是队满还是队空。tag==0tag == 0tag==0 时,若因删除导致 Q.front==Q.rearQ.front==Q.rearQ.front==Q.rear,则为队空;tag==1tag==1tag==1 时,若因插入导致 Q.front==Q.rearQ.front==Q.rearQ.front==Q.rear,则为队满。

  1. 初始化
void InitQueue(SqQueue &Q){Q.rear=Q.front=0;   // 初始化队首、队尾指针
}
  1. 判队空
bool isEmpty(SqQueue &Q){if(Q.rear==Q.front) return true;  // 队空条件else return false;
}
  1. 入队
bool EnQueue(SqQueue &Q,ElemType x){if ((Q.rear+1)%MaxSize==Q.front) return false;    // 队满 Q.data[Q.rear]=x;    Q.rear= (Q.rear+1)%MaxSize;   // 队尾指针加 1 取模return true;
}
  1. 出队
bool DeQueue(SqQueue sQ,ElemType x){if(Q.rear==Q.front) return false;      //队空,报错x=Q.data[Q.front];Q.front=(Q.front+1)%MaxSize;     //队头指针加 1 取模return true;
}

2.5 双端队列

双端队列是指允许两端都可以进行入队和出队操作的队列,

输出受限的双端队列∶允许在一端进行插入和删除,但在另一端只允许插入的双端队列称为输出受限的双端队列,如下图

输入受限的双端队列∶允许在一端进行插入和删除,但在另一端只允许删除的双端队列称为输入受限的双端队列,如下图

三、STL容器中的queue和priority queue的实现方式

priority_queue<int> big_heap;//默认构造是最大堆
priority_queue<int, vector<int>, greate<int> > small_heap; //最小堆构造方法
priority_queue<int, vector<int>, less<int> > big_heap2;//最大堆构造方法big_heap.empty()  // 判断堆是否为空
big_heap.pop()      // 弹出堆顶元素(最大值)
big_heap.push(x)    // 将元素x添加至二叉堆
big_heap.top()      // 返回堆顶元素(最大值)
big_heap.size()     // 返回堆中元素个数

【数据结构-栈和队列】详解栈和队列(代码+STL+原理)相关推荐

  1. php循环取redis队列,详解Redis和队列

    下面由Redis教程栏目给大家详解Redis和队列,希望对需要的朋友有所帮助! 概要 Redis不仅可作为缓存服务器,还可用作消息队列.它的列表类型天生支持用作消息队列.如下图所示: 由于Redis的 ...

  2. java 消息队列详解_Java消息队列-Spring整合ActiveMq的详解

    本篇文章主要介绍了详解Java消息队列-Spring整合ActiveMq ,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 1.概述 首先和大家一起回顾一下Java 消息服 ...

  3. 数据结构《顺序栈》知识点详解+C语言完整代码-超详细

    顺序栈 栈 1. 定义 2. 逻辑结构 3. 存储结构 4. 运算规则 5. 实现方式 C语言代码实现 1. 顺序栈的表示 2. 结构体 3.初始化 4.入栈 5.出栈 6. 取栈顶元素 7.求长 8 ...

  4. 【数据结构-树】3.详解二叉排序树(理论+代码)

    二叉排序树 二叉排序树的定义 二叉排序树也称为二叉查找树.二叉排序树或者是一棵空树,或者是一棵具有如下特性的非空为茶树 若左子树非空,则左子树所有结点关键字值均小于根结点的关键字值 若右子树非空,则右 ...

  5. HBase数据结构与基本语法详解

    HBase数据结构与基本语法详解.背景: 阅读新闻 [日期:2019-01-06] 来源:Linux社区 作者:Linux [字体:大 中 小] HBase中的表一般有这样的特点: 1 大:一个表可以 ...

  6. 【数据结构与算法】详解什么是图结构,并用代码手动实现一个图结构

    本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...

  7. C/C++堆、栈及静态数据区详解

    五大内存分区 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.下面分别来介绍: 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面 ...

  8. 堆、栈及静态数据区详解

    堆.栈及静态数据区详解 五大内存分区 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储 ...

  9. 40000+字超强总结?阿里P8把Java全栈知识体系详解整理成这份PDF

    40000 +字长文总结,已将此文整理成PDF文档了,需要的见文后下载获取方式. 全栈知识体系总览 Java入门与进阶面向对象与Java基础 Java 基础 - 面向对象 Java 基础 - 知识点 ...

  10. JavaScript数据结构与算法——队列详解(下)

    接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...

最新文章

  1. 字符串json怎么把双引号去掉_Java Json字符串的双引号("")括号如何去掉
  2. aws lambda使用_使用AWS Lambda安排Slack消息
  3. Java 性能优化的 45 个细节
  4. ubuntu升级python_ubuntu升级python版本
  5. 除了数据还是数据?2018年5大 AI (人工智能)预测
  6. 关于css position和scroll事件的一些理解
  7. 机房收费系统=三层+设计模式
  8. 马路军团求职平台用户需求
  9. 修改Cmder命令提示符
  10. html访问手机相册,使用HTML5的FileReader读取手机图片(还可选择拍照), 并自动异步上传到服务器上...
  11. Integer的缓存机制
  12. linux实验报告makefile,linux实验二交叉编译和Makefile实验报告.doc
  13. Java Kafka 简单示例
  14. C#Redis 事务操作
  15. 曼彻斯特编码_网络工程师考点集锦(数字编码和编码效率)
  16. 2019最新版Eclipse下载与安装
  17. android交叉编译工具链,NDK 交叉编译工具链使用
  18. 科学道德与学风-2021雨课堂答案-第5章
  19. 【Java】Java基础之Lambda表达式和Stream流
  20. 5G SA的网络架构和关键技术

热门文章

  1. c/c++头文件函数一览表
  2. DIV层跟随鼠标位置显示提示
  3. Android开发系列(三)
  4. Windows下的cmd小技巧
  5. php 策略模式实现原理,php 策略模式原理与应用深入理解
  6. 微众WeCross 跨链平台(6)UBI通用区块链接口
  7. 《图解密码技术》分组密码(5) 输出反馈OFB模式
  8. 近世代数--内直积--内直积是什么?充要条件?
  9. Have a tea -(极客大挑战(SMC,fork
  10. Kubernetes通过containerd访问registry的30443端口