当前位置: 首页 > news >正文

栈和队列

栈和队列都属于限制了插入、删除操作的表。栈要求插入、删除操作都只能作用在一端;队列要求插入、删除操作不能作用在同一端。

因此,栈是先进后出的一种数据结构,队列是先进先出的数据结构。

C++的标准库中有栈模板,它的详细操作介绍请参考这篇博文:http://www.cnblogs.com/yeqluofwupheng/p/6711265.html

下面从算法和应用等方面介绍栈。

顺序栈和链栈

栈的实现可以是建立在数组或链表上的,建立在数组上的顺序栈和建立在链表上的链栈也有一些区别:

  • 在顺序栈中,定义了栈的栈底指针(存储空间首地址base)、栈顶指针top以及顺序存储空间的大小stacksize;而对于链栈来说,它只定义栈顶指针。
  • 顺序栈和链栈的top指针有区别,顺序栈的top指针指向栈定的空元素处,top-1才指向栈顶元素,而链栈的top指针相当于链表的head指针一样,指向实实在在的元素。
  • 在空间上,顺序表是静态分配的,而链表则是动态分配的;就存储密度来说:顺序表等于1,而链式表小于1。
  • 顺序栈由于有栈空间大小,所以一般栈中的空间是有限制的,而链栈是动态分配,它的空间大小等于可用的整个内存空间。

链栈的简单实现:

class LinkStack{
public:
    bool isEmpty(){ return !head; }
    void push(int val){
        ListNode *r = new ListNode(val);
        r->next = head;
        head = r;
    }
    void pop(){
        if (isEmpty())return;
        ListNode *p = head;
        head = head->next;
    }
    int top(){
        if (isEmpty())return -1;//抛出异常
        return head->val;
    }
private:
    ListNode *head = nullptr;
};

Min Stack

LeetCode中有一道题,设计最小栈Min Stack。支持push、top、pop、getMin这四种操作。

  • push(x) -- 将x入栈.
  • pop() -- 栈顶元素出栈.
  • top() -- 得到栈顶元素的值.
  • getMin() -- 返回栈中最小值的元素.

使用双栈来实现最小栈

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {

    }

    void push(int x) {
        if (s.empty() || s.top().second > x){//需要更新最小值
            s.push(make_pair(x, x));
        }
        else{//上一个的最小值是当前的最小值
            s.push(make_pair(x, s.top().second));
        }
    }

    void pop() {
        s.pop();
    }

    int top() {
        return s.top().first;
    }

    int getMin() {
        return s.top().second;
    }
private:
    stack<pair<int,int>>s;//first存当前位置的实际值,second存当前位置的最小值
};

Implement Stack using Queues

使用队列来实现栈,要求包含下面的操作:

  • push(x) -- 将x入栈.
  • pop() -- 栈顶元素出栈.
  • top() -- 得到栈顶元素的值.
  • empty() -- 判断栈是否为空.
class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {

    }

    /** Push element x onto stack. */
    void push(int x) {
        Q.push(x);
        for (size_t i = 1; i < Q.size(); i++){
            Q.push(Q.front());
            Q.pop();
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int v = Q.front();
        Q.pop();
        return v;
    }

    /** Get the top element. */
    int top() {
        return Q.front();
    }

    /** Returns whether the stack is empty. */
    bool empty() {
        return Q.empty();
    }
private:
    queue<int>Q;
};

栈的应用

数制转换:即将十进制转换为K进制;

括号匹配:{}、()、[]三种括号的嵌套和匹配。

表达式求值:给定一个算数表达式字符串,求出它的值。

中缀与后缀表达式的转换:将一个中缀表达式转换成后缀表达式。

队列

Implement Queue using Stacks

使用栈实现队列,要求包含下面操作:

  • push(x) -- 将x入队.
  • pop() -- 队列的头部的元素出队.
  • peek() -- 查看队列的头部的元素.
  • empty() -- 返回队列是否为空.

双栈实现队列。

class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {

    }

    /** Push element x to the back of queue. */
    void push(int x) {
        sin.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int v = 0;
        if (sout.empty()){
            while (!sin.empty()){
                sout.push(sin.top());
                sin.pop();
            }
        }
        v = sout.top();
        sout.pop();
        return v;
    }

    /** Get the front element. */
    int peek() {
        if (sout.empty()){
            while (!sin.empty()){
                sout.push(sin.top());
                sin.pop();
            }
        }
        return sout.top();
    }

    /** Returns whether the queue is empty. */
    bool empty() {
        return sin.empty() && sout.empty();
    }
private:
    stack<int>sin,sout;
};

队列的应用

例如,打印机中的任务队列,售票时每个窗口的队列,系统中的消息队列等,很多场景需要用到队列这一结构。

双端队列

双端队列对应C++标准库中的deque容器,双端队列是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

deque采用分块的线性存储结构来存储数据,每块的大小一般为512B,将之称为deque块,所有的deque块使用一个map块进行管理,每个map数据项记录各个deque块的首地址。这样的话,deque块在头部和尾部都可以插入和删除,而不需要移动其他元素(使用

push_back()方法在尾部插入元素,会扩张队列,而使用push_front()方法在首部插入元素和使用insert()方法在中间插入元素,只是将原位置上的元素进行覆盖,不会增加新元素)一般来说,当考虑到容器元素的内存分配策略和操作的性能时deque相当于vector更有优势。

deque的构造方法

  • deque<type> deq                                        创建一个没有任何元素的双端队列
  • deque<type> deq(otherDeq)                    用另一个类型相同双端队列初始化该双端队列
  • deque<type> deq(size)                              初始化一个固定size的双端队列
  • deque<type> deq(n, element)                  初始化n个相同元素的双端队列
  • deque<type> deq(begin,end)                   初始化双端队列中的某一段元素,从begin 到 end - 1

deque的操作

  • deq.assign(n,elem)               赋值n个元素的拷贝给双端队列
  • deq.assign(beg,end)            赋值一段迭代器的值给双端队列
  • deq.push_front(elem)           添加一个元素在开头
  • deq.pop_front()                       删除第一个元素
  • deq.at(index)                           取固定位置的元素
  • deq[index]                                取固定位置的元素
  • deq.front()                                返回第一个元素(不检测容器是否为空)
  • deq.back()                                返回最后一个元素(不检测容器是否为空)

输入受限的双端队列

即:一端既能输入又能输出,另一端只能输出的双端队列;

输出受限的双端队列

即:一端既能输入又能输出,另一端只能输入的双端队列;

一个经典问题:

如果以1、2、3、4为一个双端队列的输入序列,则满足下面条件的输出序列是什么?

1)能够通过一个输入受限的双端队列得到,但不能通过输出受限的双端队列得到;

2)能够通过一个输出受限的双端队列得到,但不能通过输入受限的双端队列得到;

3)既不能通过一个输入受限的双端队列得到,又不能通过输出受限的双端队列得到;

输入受限的双端队列不可以得到:4213、4231

输出受限的双端队列不可以得到:4132、4231

因此上面的答案分别是

1)4132;2)4213;3)4231

转载于:https://www.cnblogs.com/yeqluofwupheng/p/7420675.html

相关文章:

  • 查看索引的状态
  • 二级MSOffice高级应用考试大纲(2013年版)
  • POJ 1830 开关问题 高斯消元
  • CAN协议,系统结构和帧结构
  • New Concept English Two 11 28
  • centos 配置sudo记录日志
  • Android图文混排实现方式详解
  • crossdomain.xml解决跨域问题
  • git克隆远程项目并创建本地对应分支
  • compile FFMPEG under windows
  • gulp 和 Browsersync 的联合使用
  • 大数据计算框架与平台
  • 甲骨文推Oracle Exadata Cloud Machine 专有云产品线进一步完善
  • 全面解析光纤光缆、网线和电缆的区别
  • Java保留两位小数的方法
  • 【笔记】你不知道的JS读书笔记——Promise
  • interface和setter,getter
  • JavaScript对象详解
  • jdbc就是这么简单
  • JS+CSS实现数字滚动
  • js数组之filter
  • Laravel 中的一个后期静态绑定
  • PHP 小技巧
  • Redis 中的布隆过滤器
  • uva 10370 Above Average
  • 回顾2016
  • 检测对象或数组
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 微信小程序填坑清单
  • 数据库巡检项
  • #include
  • #includecmath
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (26)4.7 字符函数和字符串函数
  • (arch)linux 转换文件编码格式
  • (差分)胡桃爱原石
  • (二)斐波那契Fabonacci函数
  • (二)构建dubbo分布式平台-平台功能导图
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (一)appium-desktop定位元素原理
  • (转)3D模板阴影原理
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET6 命令行启动及发布单个Exe文件
  • .NET分布式缓存Memcached从入门到实战
  • .NET轻量级ORM组件Dapper葵花宝典
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • @Autowired多个相同类型bean装配问题
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • @EnableAsync和@Async开始异步任务支持
  • @NestedConfigurationProperty 注解用法
  • [ C++ ] STL_list 使用及其模拟实现