• 【编程之美】3.7 队列取最大值操作问题 ☆


    之前写过栈的,以为队列的也一样,结果一点都不一样。写了好久啊。

    因为栈是后进先出,先进去的数字不会影响后面的数字;而队列是先进先出,后进去的会受先进入的数字的影响。

    比如: (先)  1 9 3 8 4 (后)  这样的序列

    栈存储        1 9               就可以了,因为9弹出后,自然 1 就是最大的

    队列则不行,如果按上面存储9弹出后 剩下 3 8 4,8是最大的,没有存储。

    我的方法,保存一个max的队列

    入队列时: 如果新值比 max的最前面的元素大,那么把max清空,压入新值。  因为这个元素比所有值大,并且比所有值都晚弹出。

    如果不满足上面条件,但是新值比数据队列的最后一个元素大或等于,把新值压入max队列。因为队列只剩下新值上一个元素和新值时,该新值就是最大的数字。

    出队列时:如果弹出的数字和max队列最前面的数字一样大,弹出max中的元素

    获得最大元素:获得max的最前面的元素。

    #include <iostream>
    #include <queue>
    using namespace std;
    
    
    class My_Queue
    {
    public:
        My_Queue(){};
        void EnQueue(int v)
        {
            if(max.empty())
            {
                max.push(v);
            }
            else
            {
                if(v > max.front())
                {
                    while(!max.empty())
                    {
                        max.pop();
                    }
                    max.push(v);
                }
                else if(v >= data.back())
                {
                    max.push(v);
                }
            }
            data.push(v);
        }
    
        int DeQueue()
        {
            if(data.empty())
            {
                printf("error");
                return 0;
            }
    
            if(!max.empty() && data.front() == max.front())
            {
                max.pop();
            }
            int del = data.front();
            data.pop();
            return del;
        }
    
        int MaxElement()
        {
            if(max.empty())
            {
                printf("no data
    ");
                return 0;
            }
            return max.front();
        }
    
        queue<int> data;
        queue<int> max;
    };
    
    
    
    int main()
    {
        My_Queue q;
        q.EnQueue(1);
        q.EnQueue(5);
        q.EnQueue(9);
        q.EnQueue(3);
        q.EnQueue(8);
        q.EnQueue(4);
        q.EnQueue(8);
        q.EnQueue(11);
    
        for(int i = 0; i < 8; i++)
        {
            printf("max:%d ", q.MaxElement());
            printf("del:%d
    ", q.DeQueue());
        }
    
        return 0;
    }

    书上答案:

    用两个栈A, B来构造队列,因为栈取最大可以O(1),利用栈使得队列取最大也是O(1)

    数据入队列时:都压入栈B

    数据出队列时: 若A为空,则把B的数据依次弹出给A,再弹出A的最后一个元素  (两次后进先出就变成了先进先出)

                         若A不空,直接弹出A的最后一个元素

    取最大值: 取栈A 和 栈B 最大值里 更大的那一个

  • 相关阅读:
    centos安装docker
    centos 安装nginx遇到的问题
    IntelliJ IDEA 2018.3 永久激活 破解[Windows]
    mysql 8.0.12重置密码
    mysql8.*忘记密码
    CentOS安装Hadoop
    执行 systemctl start firewalld 命令后出现Failed to start firewalld.service: Unit is masked
    Centos操作命令
    解决CentOS7关闭/开启防火墙出现Unit iptables.service failed to load: No such file or directory.
    Java并发Lock接口
  • 原文地址:https://www.cnblogs.com/dplearning/p/4114395.html
Copyright © 2020-2023  润新知