Day10代码随想录队列

Day10:

理论基础

栈和队列的原理:栈是先进后出,队列是先进先出,

栈与队列理论1

思考以下问题:

  1. C++中stack 是容器么?
  2. 我们使用的stack是属于哪个版本的STL?
  3. 我们使用的STL中stack是如何实现的?
  4. stack 提供迭代器来遍历stack空间么?

栈与队列理论2

栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。

栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能)。

所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。

那么问题来了,STL 中栈是用什么容器实现的?

从下图中可以看出,栈的内部结构,栈的底层实现可以是vector,deque,list 都是可以的, 主要就是数组和链表的底层实现。

栈与队列理论3

我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。

我们常用的SGI STL,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的底层结构。

deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。

SGI STL中 队列底层实现缺省情况下一样使用deque实现的。

我们也可以指定vector为栈的底层实现,初始化语句如下:

std::stack<int, std::vector<int> > third;  // 使用vector为底层容器的栈

1

刚刚讲过栈的特性,对应的队列的情况是一样的。

队列中先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。

也可以指定list 为起底层实现,初始化queue的语句如下:

std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列

1

所以STL 队列也不被归类为容器,而被归类为container adapter( 容器适配器)。

我这里讲的都是C++ 语言中的情况, 使用其他语言的同学也要思考栈与队列的底层实现问题, 不要对数据结构的使用浅尝辄止,而要深挖其内部原理,才能夯实基础。

232.用栈实现队列

使用栈实现队列的下列操作:

push(x) – 将一个元素放入队列的尾部。
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.pop();   // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。

  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

    此题目用两个栈模拟队列的操作,根据二者一个栈后进先出,另一个队列先进先出的特性,考虑两个栈来模拟队列的一系列的操作。主要定义两个栈,一个模拟输入的输入栈,另一个模拟输出的输出栈。

class MyQuene
{
    stack<int> stIn;
    stack<int> stOut;
	MyQuene()
    {
        
	}
    void push(int x)
    {
        stIn.push(x);
	}
    int pop()
    {
        if(stOut.empty())//如果输出栈为空则将输入栈中的元素全部输入到输出栈中。然后输出栈进行弹出
        {
            while(!stIn.empty())
            {
                stOut.push(stIn.top());
            	stIn.pop();
			}
		}
        int result = stOut.top();
        stOut.pop();
	}
    int peak()
    {
        int result=this->pop();
        stOut.push(result);
	}
    bool isempty()
    {
        return stIn.empty()&&stOut.empty();
	}
};

225. 用队列实现栈

使用队列实现栈的下列操作:

  • push(x) – 元素 x 入栈
  • pop() – 移除栈顶元素
  • top() – 获取栈顶元素
  • empty() – 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
class MyStack {
public:
    queue<int> que;  // 使用一个队列来存储栈的元素

    /** 初始化数据结构 */
    MyStack() {
        // 构造函数,用于初始化队列
    }

    /** 将元素 x 压入栈中 */
    void push(int x) {
        que.push(x);  // 将元素 x 添加到队列的尾部
    }

    /** 弹出栈顶的元素并返回该元素 */
    int pop() {
        int size = que.size();  // 获取队列的大小
        size--;  // 减去1,因为要留下一个元素作为栈顶

        // 将队列头部的元素(除了最后一个元素外)重新添加到队列尾部
        while (size--) {
            que.push(que.front());  // 将队列头部的元素添加到队列尾部
            que.pop();  // 弹出队列头部的元素
        }

        int result = que.front(); // 此时队列的头部元素就是栈的顶部元素
        que.pop();  // 弹出栈顶元素
        return result;
    }

    /** 获取栈顶元素 */
    int top() {
        return que.back();  // 返回队列尾部的元素,即栈顶元素
    }

    /** 判断栈是否为空 */
    bool empty() {
        return que.empty();  // 判断队列是否为空,从而判断栈是否为空
    }
};

这里只用了一个队列就模拟了


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值