栈和队列

本文介绍了栈和队列两种基本数据结构,栈用于存储函数调用信息,具有先进后出特性;队列则遵循先进先出原则,常用于树的宽度优先遍历。文章探讨了如何利用两个栈实现队列以及用队列实现栈的方法,同时指出这种方法在top和pop操作上的时间复杂度较高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈和队列

栈是一个非常常见的数据结构,它在计算机领域被广泛应用,比如操作系统会给每个线程创建一个栈来存储函数调用时各个函数的参数、返回地址及临时变量等。

栈是一种先进后出的数据结构,元素从顶端入栈,然后从顶端出栈。

通常栈是一个不考虑排序的数据结构,我们需要 O ( n ) O(n) O(n)的时间才能找到栈中最大或最小的元素。

队列是另外一种很重要的数据结构。队列的特点是先进先出。在树的宽度优先遍历算法中,我们在遍历某一层树的节点时,把节点的子节点放到一个队列里,以备下一层节点的遍历。

队列是一种先进先出的数据结构,元素从后端入队,然后从前端出队。

栈和队列虽然是特点针锋相对的两个数据结构,但是有意思的是他们却相互联系。比如下题:

9 用两个栈实现队列

在这里插入图片描述
双栈可以实现列表倒序。栈A一直放数据,如果要删除数据的话,将栈A的内容放入栈B,这时从栈B删除就是删除栈A栈顶的元素。如果栈A再加入新的元素,当他们再次放到栈B时,顺序和队列是一样的。删除完栈B的元素,就说明这个队列前部分删除完了,要删除后一部分了,这时从栈A(如果还有元素的话)将后一部分放入栈B,接着删除。

class CQueue {
public:
    stack<int> A;
    stack<int> B;
    CQueue() {

    }
    
    void appendTail(int value) {
        A.push(value);
    }
    
    int deleteHead() {
        if(A.empty() && B.empty()){
            return -1;
        }
        else if(B.empty()){//B空,把A中的全倒序放入B中
            while(!(A.empty())){
                B.push(A.top());
                A.pop();
            }
            //倒序放入完成之后,B的栈顶元素删除,B的元素删完再从A拿进来!!!
            
        }
        
        int res=B.top();
        B.pop();
        return res;
        
    }
};

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

255 用队列实现栈

在这里插入图片描述
在这里插入图片描述
思路:两个队列,总是至少有一个保持是空的状态。将元素压入栈顶时,将元素入非空队列就好。top时,将非空队列除了头元素,全部放入空队列,返回头元素并将头元素放入上面的非空队列,pop时删除这个元素就好。
缺点:top和pop操作时间复杂度较高是 O ( n ) O(n) O(n)。要先放入非空队列。插入操作时间复杂度是 O ( 1 ) O(1) O(1),直接放入就好。

class MyStack {
public:
    deque<int> A;
    deque<int> B;
    /** Initialize your data structure here. */
    MyStack() {

    }
    
    /** Push element x onto stack. */
    void push(int x) {
        if(A.empty()){//A队列空,放入B
            B.push_back(x);
        }
        else{//A不空,放入A
            A.push_back(x);
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        if(A.empty() && B.empty()){
            return -1;
        }
        if(A.empty()){//A空,转到A,然后删除
            int itr = B.size();
            for(int i=0;i<itr-1;i++){
                A.push_back(B.front());
                B.pop_front();
            }
            //B还剩一个元素,返回并删除
            int res = B.front();
            B.pop_front();
            return res;
        }else{
            int itr=A.size();
            for(int i=0;i<itr-1;i++){
                B.push_back(A.front());
                A.pop_front();
            }
            //B还剩一个元素,返回并删除
            int res = A.front();
            A.pop_front();
            return res;
        }

    }
    
    /** Get the top element. */
    int top() {
         if(A.empty() && B.empty()){
            return -1;
        }
        if(A.empty()){//A空,转到A,
            
            int itr=B.size();
            for(int i=0;i<itr-1;i++){//B的size 改变了
                A.push_back(B.front());
                B.pop_front();
                
            }
            //B还剩一个元素,返回
            int res = B.front();
            A.push_back(res);
            B.pop_front();
            return res;
        }else{
            int itr=A.size();
            for(int i=0;i<itr-1;i++){
                B.push_back(A.front());
                A.pop_front();
            }
            //B还剩一个元素,返回
            int res = A.front();
            B.push_back(res);
            A.pop_front();
            return res;
        }  
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        if(A.empty() && B.empty()){//A,B都空
            return true;
        }
        else{
            return false;
        }
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

在这里插入图片描述
这个代码的push操作时间复杂度是 O ( n ) O(n) O(n),而top和pop操作的时间复杂度都是 O ( n ) O(n) O(n)。只要确保队列A中队首元素总是栈顶元素即可。

class MyStack {
public:
    /** Initialize your data structure here. */
    deque<int> A;
    deque<int> B;
    MyStack() {

    }
    
    /** Push element x onto stack. */
    void push(int x) {
        B.push_back(x);
        while(!A.empty()){
            B.push_back(A.front());
            A.pop_front();
        }
        swap(A,B);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        if(A.empty()){
            return -1;
        }
        int res = A.front();
        A.pop_front();
        return res;
    }
    
    /** Get the top element. */
    int top() {
        if(A.empty()){
            return -1;
        }
        return A.front();
        
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        if(A.empty()){
            return true;
        }
        return false;
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值