队列中取最大值操作问题

问题:
假设有这样一个拥有3个操作的队列:
1. EnQueue(v): 将v加入队列中
2. DeQueue(): 使队列中的队首元素删除并返回此元素
3. MaxElement: 返回队列中的最大元素

设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低。


思路:

(1)用两个栈设计一个新的数据类型(数据类型定义为MyStack),其中一个栈用来存放数据,另一个栈用来存放最大值,

          当插入数据时,第一个栈接受数据进行入栈操作,第二栈首先判断一下栈顶元素和插入元素的大小,如果栈顶元素小于新插入的元素,那么,第二个堆栈进行入栈操作,如果栈顶元素小于新插入的元素的大小,第二个栈不做操作!!!

         当删除元素时,第一个栈直接进行出栈操作,第二个拿出顶元素和第一个中出元素进行比较,如果相等,第二个进行出操作,否则不做操作

         由上面意思可知,第二个顶元素就是最大值

自定义的源代码为(java实现):


package com.panther.dong.beautyprogram.thirdchapter.section7;

import java.util.Stack;

/**
 * Created by panther on 15-8-20.
 */
public class MyStack {
    private Stack<Integer> stack1 = new Stack<Integer>();
    private Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int e) {
        stack1.push(e);
        if (stack2.size() == 0 || stack2.peek() < e) {
            stack2.push(e);
        }
    }

    public int pop() {
        int temp = stack1.pop();
        if (temp == stack2.peek()) {
            stack2.pop();
        }
        return temp;
    }

    public int max() {
        if (stack2.size() != 0) {
            return stack2.peek();
        } else {
            return 0;
        }
    }

    public int size() {
        return stack1.size();
    }

    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(4);
        myStack.push(8);
        myStack.push(6);
        myStack.push(5);
        myStack.push(3);
        myStack.push(9);
        myStack.push(3);
        myStack.push(14);

        System.out.println(myStack.max());
        myStack.pop();
        myStack.pop();
        myStack.pop();
        System.out.println(myStack.max());
    }
}

自定义栈的测试运行结果为:



(2)第二步,用自己定义的(MyStack)来实现队列所需的功能,进队列直接在myStack1中入,出队列,首先判断一下myStack2是否为空,不为空直接从myStack2出

如果为空,先将myStack1中的数据全部放到myStack2中,myStack2再进行出操作!!!!!最大值为myStack1和myStack2中最大值的最大值!!!!!

具体的代码实现(java代码实现):

package com.panther.dong.beautyprogram.thirdchapter.section7;

/**
 * Created by panther on 15-8-19.
 */
public class MyQueue {
    private MyStack myStack1 = new MyStack();
    private MyStack myStack2 = new MyStack();

    public void EnQueue(int element) {
        myStack1.push(element);
    }

    public int DeQueue() {
        int element = 0;
        if (myStack2.size() != 0) {
            element = myStack2.pop();
        } else {
            while (myStack1.size() != 0) {
                myStack2.push(myStack1.pop());
            }
            element = myStack2.pop();
        }
        return element;
    }

    public int MaxElement() {
        return myStack1.max() > myStack2.max() ? myStack1.max() : myStack2.max();
    }

    public static void main(String[] args) {package com.panther.dong.beautyprogram.thirdchapter.section7;

/**
 * Created by panther on 15-8-19.
 */
public class MyQueue {
    private MyStack myStack1 = new MyStack();
    private MyStack myStack2 = new MyStack();

    public void EnQueue(int element) {
        myStack1.push(element);
    }

    public int DeQueue() {
        int element = 0;
        if (myStack2.size() != 0) {
            element = myStack2.pop();
        } else {
            while (myStack1.size() != 0) {
                myStack2.push(myStack1.pop());
            }
            element = myStack2.pop();
        }
        return element;
    }

    public int MaxElement() {
        return myStack1.max() > myStack2.max() ? myStack1.max() : myStack2.max();
    }

    public static void main(String[] args) {
        MyQueue myQueue = new MyQueue();
        myQueue.EnQueue(7);
        myQueue.EnQueue(3);
        myQueue.EnQueue(5);
        myQueue.EnQueue(2);
        myQueue.EnQueue(9);
        myQueue.EnQueue(11);
        myQueue.EnQueue(21);
        myQueue.EnQueue(14);
        myQueue.EnQueue(17);
        myQueue.EnQueue(18);
        myQueue.EnQueue(4);
        myQueue.EnQueue(8);
        myQueue.EnQueue(3);
        myQueue.EnQueue(4);
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());
        System.out.println(myQueue.MaxElement());
        System.out.println(myQueue.DeQueue());

    }
}
运行结果:



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#队列(Queue)是一种先进先出(FIFO,First In First Out)的数据结构,通常用于处理任务按照它们被添加到队列的顺序进行。然而,队列本身并不支持直接查找和移除最大值或最小,因为它的设计目的是为了快速添加和删除元素队列的一端。 如果你想要在C#找到队列最大值和最小,你有几种可能的方法: 1. **创建一个辅助数据结构**:你可以使用两个(Stack),一个用来保存元素,一个用来保存已检查的元素。每次从队列弹出元素,检查其是否大于当前最小或小于当前最大值,然后更新相应。最后,元素就是最大值,另一个顶是次大或最小(取决于你的实现顺序)。 ```csharp List<int> queueElements; Stack<int> maxStack = new Stack<int>(); Stack<int> minStack = new Stack<int>(); foreach (int item in queueElements) { if (maxStack.Count == 0 || item > maxStack.Peek()) { maxStack.Push(item); } else if (minStack.Count == 0 || item < minStack.Peek()) { minStack.Push(item); } // 如果新元素小于或等于最大值,从最大值弹出 while (maxStack.Count > 0 && item <= maxStack.Peek()) { maxStack.Pop(); } // 同理,如果新元素大于或等于最小,从最小弹出 while (minStack.Count > 0 && item >= minStack.Peek()) { minStack.Pop(); } } int maxValue = maxStack.Count > 0 ? maxStack.Peek() : int.MinValue; int minValue = minStack.Count > 0 ? minStack.Peek() : int.MaxValue; ``` 2. **遍历队列**:如果你不想使用额外的数据结构,可以在遍历队列的过程维护最大值和最小。但这会使得操作的时间复杂度变为O(n^2),对于大规模数据不太高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值