• 基于堆的最大最小优先级队列的实现


    最大堆能够在O(1)的时间内取得集合中的最大值,并且在集合中加入新元素的时候,能够以O(Logn)的时间将新的元素插入到堆中。

    当取出最大的元素时,能够以O(Logn)的时间重新将堆整理成最大堆。最小堆同理。

    最大优先级队列的应用实例:基于优先级的作业调度,在所有等待调度的作业中,选择具有最大优先级作业进行处理。同时一个新的作业也可以插入到队列里面去。

    例如可以实现自己的基于优先级的多线程作业调度程序。

    最小优先级队列的应用实例:可以实现一个基于时间的作业调度程序,时间最小的被优先选择进行事件通知或者处理。Huffman编码的实现可以依靠最小优先级队列实现。

    最大最小优先级队列的C#实现:

    队列处理的数据类型:

     public interface IHeapValue
        {
            int Value { get; set; }
        }

    最大优先级队列:

     public class MaxPriorityQueue<TNode>
            where TNode : IHeapValue
        {
            private TNode[] array;
            //cursor 指向第一个空出来的位置
            private int cursor;
            public MaxPriorityQueue()
            {
                array = new TNode[32];
                cursor = 0;
            }
            public bool IsEmpty { get { return cursor <=0; } }
            public void Insert(TNode x)
            {
                if (cursor + 1 == array.Count())
                {
                    TNode[] tmparray = new TNode[array.Count() * 2];
                    array.CopyTo(tmparray, 0);
                    array = tmparray;
                }
                //往上检查是否成最大堆
                int xIndex = cursor++;
                array[xIndex] = x;
                while (xIndex / 2 >= 0)
                {
                    if (array[xIndex / 2].Value >= array[xIndex].Value) break;
                    TNode tmpNode = array[xIndex / 2];
                    array[xIndex / 2] = array[xIndex];
                    array[xIndex] = tmpNode;
                    xIndex = xIndex / 2;
                }
            }
            public TNode Maximum()
            {
                return array[0];
            }
            public TNode ExtractMax()
            {
                TNode hn = array[0];
                //把最后一个元素换到第一个 array[0]= array[cursor-1],array[cursor-1]=null;cursor--;
                array[0] = array[cursor - 1];
                array[cursor - 1] = default(TNode);
                cursor--;
                maxHeapify(0, cursor - 1, 0);
                return hn;
            }
            public void IncreaseKey(int nodeIndex, int newValue)
            {
                if (nodeIndex < cursor && array[nodeIndex].Value < newValue)
                {
                    array[nodeIndex].Value = newValue;
                    while (nodeIndex / 2 >= 0)
                    {
                        if (array[nodeIndex / 2].Value >= array[nodeIndex].Value) break;
                        TNode tmpNode = array[nodeIndex / 2];
                        array[nodeIndex / 2] = array[nodeIndex];
                        array[nodeIndex] = tmpNode;
                        nodeIndex = nodeIndex / 2;
                    }
                }
    
            }
            //由下向上建堆时使用此函数,下面已经建好,上面还没好时使用
            private void maxHeapify(int startIndex, int endIndex, int newRootIndex)
            {
    
                //int L = (newRootIndex - startIndex) * 2 + 1 + startIndex;
                int L = (newRootIndex - startIndex + 1) * 2 + startIndex - 1;//The array base is from 0.
                int R = L + 1;
                int tmpLargestIndex = newRootIndex;
                if (L <= endIndex && array[L].Value.CompareTo(array[tmpLargestIndex].Value) > 0)
                {
                    tmpLargestIndex = L;
                }
                if (R <= endIndex && array[R].Value.CompareTo(array[tmpLargestIndex].Value) > 0)
                {
                    tmpLargestIndex = R;
                }
                if (tmpLargestIndex != newRootIndex)
                {
                    //swap array[tmpLargestIndex] and array[newRootIndex]
                    TNode tmpT = array[tmpLargestIndex];
                    array[tmpLargestIndex] = array[newRootIndex];
                    array[newRootIndex] = tmpT;
                    //MaxHeapify the child branch, the newRootIndex= tmpLargestIndex
                    maxHeapify(startIndex, endIndex, tmpLargestIndex);
                }
            }
        }
    MaxPriorityQueue

    最小优先级队列:

      public class MinPriorityQueue<TNode>
            where TNode : IHeapValue
        {
            private TNode[] array;
            //cursor 指向第一个空出来的位置
            private int cursor;
            public MinPriorityQueue()
            {
                array = new TNode[32];
                cursor = 0;
            }
            public bool IsEmpty { get { return cursor <= 0; } }
            public void Insert(TNode x)
            {
                if (cursor + 1 == array.Count())
                {
                    TNode[] tmparray = new TNode[array.Count() * 2];
                    array.CopyTo(tmparray, 0);
                    array = tmparray;
                }
                //往上检查是否成最小堆
                int xIndex = cursor++;
                array[xIndex] = x;
                while (xIndex / 2 >= 0)
                {
                    if (array[xIndex / 2].Value <= array[xIndex].Value) break;
                    TNode tmpNode = array[xIndex / 2];
                    array[xIndex / 2] = array[xIndex];
                    array[xIndex] = tmpNode;
                    xIndex = xIndex / 2;
                }
            }
            public TNode Minimum()
            {
                return array[0];
            }
            public TNode ExtractMin()
            {
                TNode hn = array[0];
                //把最后一个元素换到第一个 array[0]= array[cursor-1],array[cursor-1]=null;cursor--;
                array[0] = array[cursor - 1];
                array[cursor - 1] = default(TNode);
                cursor--;
                minHeapify(0, cursor - 1, 0);
                return hn;
            }
            public void DecreaseKey(int nodeIndex, int newValue)
            {
                if (nodeIndex < cursor && array[nodeIndex].Value < newValue)
                {
                    array[nodeIndex].Value = newValue;
                    while (nodeIndex / 2 >= 0)
                    {
                        if (array[nodeIndex / 2].Value <= array[nodeIndex].Value) break;
                        TNode tmpNode = array[nodeIndex / 2];
                        array[nodeIndex / 2] = array[nodeIndex];
                        array[nodeIndex] = tmpNode;
                        nodeIndex = nodeIndex / 2;
                    }
                }
    
            }
            //由下向上建堆时使用此函数,下面已经建好,上面还没好时使用
            private void minHeapify(int startIndex, int endIndex, int newRootIndex)
            {
    
                //int L = (newRootIndex - startIndex) * 2 + 1 + startIndex;
                int L = (newRootIndex - startIndex + 1) * 2 + startIndex - 1;//The array base is from 0.
                int R = L + 1;
                int tmpLargestIndex = newRootIndex;
                if (L <= endIndex && array[L].Value.CompareTo(array[tmpLargestIndex].Value) < 0)
                {
                    tmpLargestIndex = L;
                }
                if (R <= endIndex && array[R].Value.CompareTo(array[tmpLargestIndex].Value) < 0)
                {
                    tmpLargestIndex = R;
                }
                if (tmpLargestIndex != newRootIndex)
                {
                    //swap array[tmpLargestIndex] and array[newRootIndex]
                    TNode tmpT = array[tmpLargestIndex];
                    array[tmpLargestIndex] = array[newRootIndex];
                    array[newRootIndex] = tmpT;
                    //MaxHeapify the child branch, the newRootIndex= tmpLargestIndex
                    minHeapify(startIndex, endIndex, tmpLargestIndex);
                }
            }
        }
    MinPriorityQueue

    基于控制台输出的测试调用方法:

      MaxPriorityQueue<IHeapValue> maxheap = new MaxPriorityQueue<IHeapValue>();
                MinPriorityQueue<IHeapValue> minheap = new MinPriorityQueue<IHeapValue>();
                List<IHeapValue> list = new List<IHeapValue>();
                Random rnd = new Random(DateTime.Now.Millisecond);
                for (int i = 0; i < 10; i++)
                {
                    HeapNode hn = new HeapNode() { Value = rnd.Next(0, 100) };
                    list.Add(hn);
                    maxheap.Insert(hn);
                    minheap.Insert(hn);
                }
                Console.WriteLine("RandomData:");
                list.ForEach(n => Console.Write("{0},", n.Value));
                Console.WriteLine(Environment.NewLine + "MaxHeapOutput:");
                while (!maxheap.IsEmpty)
                {
                    Console.Write("{0},", maxheap.ExtractMax().Value);
                }
                Console.WriteLine(Environment.NewLine + "MinHeapOutput:");
                while (!minheap.IsEmpty)
                {
                    Console.Write("{0},", minheap.ExtractMin().Value);
                }
                Console.ReadKey();
    调用方法

    输出:

    作者:Andy Zeng

    欢迎任何形式的转载,但请务必注明出处。

     http://www.cnblogs.com/andyzeng/p/3702401.html

  • 相关阅读:
    pytorch 文本输入处理
    理解 on-policy 和 off-policy
    Monte Carlo与TD算法
    Monte Calro Tree Search (MCTS)
    强化学习概览
    linux 服务器 keras 深度学习环境搭建
    sed和awk学习整理
    linux shell编程进阶学习(转)
    gdb调试:
    MySQL C API 访问 MySQL 示例
  • 原文地址:https://www.cnblogs.com/andyzeng/p/3702401.html
Copyright © 2020-2023  润新知