優先隊列C#版

来源:互联网 发布:sql 日志回滚 编辑:程序博客网 时间:2024/05/29 07:35

基本原理是構造一個最小堆,入隊和出隊就是一個維護最小堆的過程。

入隊的時候將元素和其父節點比較,如果小於父節點就與之交換位置,重復這個過程直到該元素不再小於其父節點。

出隊的時候將堆頂的元素彈出,將隊尾的元素移到隊首,然後進行小堆化的遞歸操作。

入隊和出隊所需的步驟和堆的高度成正比,其時間複雜度為O(logN),空間複雜度為O(1)

    class PriorityQueue<T>    {        private const int DefaultCapacity = 16;        private List<T> _heap;        private IComparer<T> _comparer;        public PriorityQueue() : this(DefaultCapacity) { }        public PriorityQueue(IComparer<T> comparer) : this(DefaultCapacity, comparer) { }        public PriorityQueue(int capacity, IComparer<T> comparer = null)        {            _heap = new List<T>(capacity);            _comparer = (comparer == null) ? Comparer<T>.Default : comparer;        }        public int Count        {            get            {                return _heap.Count;            }        }        public T Top        {            get            {                if (_heap.Count == 0) throw new InvalidOperationException();                return _heap[0];            }        }        public void Enqueue(T value)        {            int idx = _heap.Count;            _heap.Add(value);            while (idx > 0)            {                int p = (idx - 1) >> 1;                if (_comparer.Compare(value, _heap[p]) >= 0) break;                Common.Swap<T>(_heap, idx, p);                idx = p;            }        }        public T Dequeue()        {            var top = Top;            int last = _heap.Count - 1;            _heap[0] = _heap[last];            _heap.RemoveAt(last);            if (_heap.Count > 0)            {                MinHeapify(0);            }            return top;        }        private void MinHeapify(int idx)        {            int l = (idx << 1) + 1;            int r = l + 1;            int min = idx;            if (l < _heap.Count && _comparer.Compare(_heap[l], _heap[idx]) < 0)            {                min = l;            }            if (r < _heap.Count && _comparer.Compare(_heap[r], _heap[min]) < 0)            {                min = r;            }            if (min != idx)            {                Common.Swap<T>(_heap, min, idx);                MinHeapify(min);            }        }    }

 

    static class Common    {        public static void Swap<T>(IList<T> A, int i, int j)        {            T tmp = A[i];            A[i] = A[j];            A[j] = tmp;        }    }

 

實現的時候内部採用氾型列表,代碼要比使用數組簡練。

優先級的次序可以通過改變比較接口來實現,非常方便。


<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击