算法笔记(堆实现的最大优先队列)

本文详细介绍了如何使用最大堆实现优先队列,包括队列元素类QueueElement和最大堆队列MaxHeapQueue的实现细节。通过实例演示了增加关键值、提取最大值等操作。

采用最大堆实现的优先队列,QueueElement是队列元素类,包含一个卫星数据成员和一个权重Key值:

 
public class QueueElement<T>
    {
        public int KeyValue{get;internal set;}
        public T Element{get;private set;}
        public QueueElement(T Item,int KeyVal)
        {
            KeyValue = KeyVal;
            Element = Item;
        }
    }
    public class MaxHeapQueue<T> 
    {
        private List<QueueElement<T>> _queueValues = new List<QueueElement<T>>();
        public int Count
        {
            get
            {
                return _queueValues.Count;
            }
        }
        public T GetMaximum()
        {
            return _queueValues[0].Element;
        }
        public T ExtractMax()
        {
            if (_queueValues.Count <= 0)
            {
                throw new Exception("队列为空");
            }
            T theMax = _queueValues[0].Element;
            int theTail = Count -1;
            _queueValues[0] = _queueValues[theTail];
            _queueValues.RemoveAt(theTail);
            MaxHeapify(0);
            return theMax;
        }
        public void MaxHeapify(int i)
        {
            int HeapSize = Count;
            int theL = HeapL(i);
            int theR = HeapR(i);
            int thelargest = i;
            if (theL < HeapSize && _queueValues[theL].KeyValue> _queueValues[thelargest].KeyValue)
            {
                thelargest = theL;
            }
            if (theR < HeapSize && _queueValues[theR].KeyValue> _queueValues[thelargest].KeyValue)
            {
                thelargest = theR;
            }
            if (thelargest != i)
            {
                SwapElement(i, thelargest);
                MaxHeapify(thelargest);
            }
        }

        public void IncreaseKey(Func<T, bool> SelectFunc, int NewKey)
        {
            int theIndex = -1;
            for (int i = 0; i < Count; i++)
            {
                if (SelectFunc(_queueValues[i].Element) == true)
                {
                    theIndex = i;
                    break;
                }
            }
            if (theIndex < 0)
            {
                return;
            }
            if (_queueValues[theIndex].KeyValue >= NewKey)
            {
                return;
            }
            _queueValues[theIndex].KeyValue = NewKey;
            UpAdjust(theIndex);
        }
        private void UpAdjust(int i)
        {
            int theIndex = i;
            int thePIndex = HeapP(theIndex);
            while (thePIndex >= 0 && _queueValues[theIndex].KeyValue > _queueValues[thePIndex].KeyValue)
            {
                SwapElement(thePIndex, theIndex);
                theIndex = thePIndex;
                thePIndex = HeapP(theIndex);
            }
        }
        public void IncreaseKey(int i, int NewKey)
        {
            int theIndex = i;
            if (_queueValues[theIndex].KeyValue >= NewKey)
            {
                return;
            }
            _queueValues[theIndex].KeyValue = NewKey;
            int thePIndex = HeapP(theIndex);
            while (thePIndex >= 0 && _queueValues[theIndex].KeyValue > _queueValues[thePIndex].KeyValue)
            {
                SwapElement(thePIndex, theIndex);
                theIndex = thePIndex;
                thePIndex = HeapP(theIndex);
            }
        }
        public void HeapDelete(Func<T, bool> SelectFunc)
        {
            int theIndex = -1;
            for (int i = 0; i < Count; i++)
            {
                if (SelectFunc(_queueValues[i].Element) == true)
                {
                    theIndex = i;
                    break;
                }
            }
            if (theIndex < 0)
            {
                return;
            }
            SwapElement(theIndex, Count - 1);
            _queueValues.RemoveAt(Count-1);
            if (theIndex < Count)
            {
                int theP = HeapP(theIndex);
                bool theUp = false;
                if (theP >= 0)
                {
                    if (_queueValues[theIndex].KeyValue > _queueValues[theP].KeyValue)
                    {
                        UpAdjust(theIndex);
                        theUp = true;
                    }
                }
                if(theUp==false)
                {
                    MaxHeapify(theIndex);
                }
            }
            
        }
        private void SwapElement(int i, int j)
        {
            QueueElement<T> theTmp = _queueValues[i];
            _queueValues[i] = _queueValues[j];
            _queueValues[j] = theTmp;
        }
        public void HeapInsert(T Element, int Key)
        {
            _queueValues.Add(new QueueElement<T>(Element, int.MinValue));
            IncreaseKey(Count-1, Key);
        }
        private int HeapL(int i)
        {
            return i * 2 + 1;
        }
        private  int HeapR(int i)
        {
            return i * 2 + 2;
        }
        private  int HeapP(int i)
        {
            return (i + 1) / 2 - 1;
        }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值