《编程之美》-取队列中的最大值(读书分享)

题目:设计一种数据结构和算法,让取队列最大值的操做的事件复杂度降到最低。对队列操做后依然可以简便取出最大值。


对于栈来说,Push和Pop均是在栈顶完成的,因此很容维护最大值,并且他的时间复杂度是O(1),基本实现以下所示: 算法

1.栈类: 数据结构

public class MyStack
    {
        private int _capacity;
        private int[] _stackItems;
        private int _maxStackItemIndex;
        private int _stackTop;
        private int[] _link2NextMaxitem;


        public MyStack(int capacity)
        {
            _capacity = capacity;
            _stackTop = -1;
            _maxStackItemIndex = -1;
            _link2NextMaxitem = new int[_capacity];
            _stackItems = new int[_capacity];
        }
        public void Push(int item) {//压栈
            _stackTop++;
            if (_stackTop >= _capacity)
            {
               return false;//越界了
            }
            else
            {
                _stackItems[_stackTop] = item;
                //维护列表,经典, 不管堆栈如何变化_link2NextMaxItem[..._link2NextMaxItem[_link2NextMaxItem[_maxStackItemIndex]]]如此环环相扣的数据保存模式保证了“当时”注意这里是“当时的”第二大数的索引老是能够经过当前的_link2NextMaxItem[_maxStackItemIndex]来得到(同时发生的事情是最大的项被弹出,也就是pop函数里面发生的事情,第二大数成了最大的了),_stackItems[_maxStackItemIndex]则是一直保存着最大项,

                if (item > Max())
                {                                                                                               _link2NextMaxitem[_stackTop] = _maxStackItemIndex;//如下两句顺序不能变,思考一下童鞋
                 _maxStackItemIndex = _stackTop; 
                                                                        
                } else   _link2NextMaxitem[_stackTop] = -1;


            }
        }
        public int Pop() {//弹出元素
            int rt = 0;
            if (_stackTop < 0)
                throw new Exception("Queue is null");


            rt = _stackItems[_stackTop];
            //维护列表
            if (_stackTop == _maxStackItemIndex)
            {
                _maxStackItemIndex = _link2NextMaxitem[_stackTop];
            }
            _stackTop--;
            return rt;
        }
        public int Max()    //取最大    
        {
            if (_maxStackItemIndex >= 0)
                return _stackItems[_maxStackItemIndex];
            else
                return -1;
        }


        public bool IsEmpty()
        {
            return _stackTop == -1;
        }
     
    }
  

联系上面思想,用两堆栈实现一个队列:队列入队的实现:利用栈B入栈全部元素;队列出队的实现:将栈B中的元素放入栈A,对栈A进行出栈操做正好知足队列元素的出队顺序要求 数据结构和算法

2.队列类(使用了1中定义的堆栈类做为队列的底层数据结构来实现),按照流程画个图就明白了: 函数

/// 队列类

    public class MyQueue
    {
        //利用堆栈与队列的类似性,用两个堆栈来实现队列
        private MyStack _stacka;
        private MyStack _stackb;

        public MyQueue(int capacity)
        {
            _stacka = new MyStack(capacity);
            _stackb = new MyStack(capacity);
        }

        public void Enqueue(int item)
        {
            _stackb.Push(item);
        }

        public int Dequeue()
        {
            if (_stacka.IsEmpty())
            {
                while (!_stackb.IsEmpty())
                    _stacka.Push(_stackb.Pop());
            }
            return _stacka.Pop();
        }

        public int Max()
        {
            return Math.Max(_stacka.Max(), _stackb.Max());
        }
    }
相关文章
相关标签/搜索