zoukankan      html  css  js  c++  java
  • 数据结构中的堆

    一:堆排序

         堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。下面附上简单C#简单实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Heap
    {
        /// <summary>
        /// 堆排序实现
        /// </summary>
        class HeapSort
        {
            public static void Sort<T>(T[] originArr) where T : IComparable
            {
                //首先建堆
                BuildMaxHeap<T>(originArr);
    
                //在一个堆上在进行排序
                RealSort<T>(originArr);
            }
    
           
            private static void RealSort<T>(T[] originArr) where T : IComparable
            {
                for (int i = 0; i < originArr.Length-1; i++)
                {
                    Swap<T>(originArr , 0, originArr.Length - (i+1));
                    MaxHeapIFY<T>(originArr, originArr.Length - (i + 1), 0);
                }
            }
    
            /// <summary>
            /// 1.首先是需要清楚 GetMaxObjInHeap方法的作用,是在一个堆上插入一个值,并保证插入后堆的性质不变
            /// 2.堆其实是满足完全二叉树的性质的,也就是 叶子节点 = (总结点+1)/2  或者 总结点 / 2
            /// 3.把每个叶子节点看做一个独立的最大堆,自底而上构建最大堆
            /// </summary>
            private static void BuildMaxHeap<T>(T[] originArr) where T : IComparable
            {
                int len = originArr.Length / 2;
                for (int i = len; i >= 0 ; i--)
                {
                    MaxHeapIFY<T>(originArr,originArr.Length, i);
                }
            }
    
    
            /// <summary>
            /// 堆操作中核心方法,并维护最大堆的性质
            /// 假设originList是一个最大堆,实现在堆固定位置插入元素,并同时保证最大堆的性质
            /// </summary>
            private static void MaxHeapIFY<T>(T[] originList, int heapSie, int pos) where T : IComparable
            {
                int len = heapSie;
                int largest = 0;
                int cLeft = pos * 2;
                int cRight = pos * 2 + 1;
                while (cLeft < len || cRight < len)
                {
                    largest = cLeft;
                    if (cRight < len && originList[cLeft].CompareTo(originList[cRight]) < 0)
                    {
                        largest = cRight;
                    }
                    if (originList[pos].CompareTo(originList[largest]) >= 0)
                    {
                        break;
                    }
                    else
                    {
                        Swap<T>(originList, pos, largest);
                        pos = largest;
                        cLeft = pos * 2;
                        cRight = pos * 2 + 1;
                    }
    
                }
            }
    
            /// <summary>
            /// 数组中两个元素交换
            /// </summary>
            private static void Swap<T>(T[] originList, int posFirst, int posSec) where T : IComparable
            {
                T temp = originList[posFirst];
                originList[posFirst] = originList[posSec];
                originList[posSec] = temp;
            }
    
            public static void PrintArr<T>(T[] arr)
            {
                for (int i = 0; i < arr.Length; i++)
                {
                    Console.Write(arr[i] + " , ");
                }
                Console.WriteLine("");
                Console.WriteLine("==================");
    
            }
        }
    }

    二,优先队列

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Heap
    {
        /// <summary>
        /// 优先队列实现
        /// </summary>
        class PriorityQueue<T> where T:IComparable
        {
            private List<T> queue;
            public PriorityQueue(int size = 10)
            {
               queue = new List<T>(size);
            }
    
            public PriorityQueue<T> Add(T t)
            {
                if (queue.Count <= 0)
                {
                    queue.Add(t);
                }
                else
                {
                    queue.Add(t);
                    HeapIncreaseKey(t, queue.Count -1, true);
                }
                return this;
            }
    
            public T Pop()
            {
                if (queue.Count <= 0) return default(T);
    
                Swap(queue, 0, queue.Count - 1);
                MaxHeapIFY(queue, queue.Count - 1, 0);
    
                T max = queue[queue.Count - 1];
                queue.RemoveAt(queue.Count - 1);
                return max;
            }
    
            /// <summary>
            /// 堆操作中核心方法,并维护最大堆的性质
            /// 假设originList是一个最大堆,实现在堆固定位置插入元素,并同时保证最大堆的性质
            /// </summary>
            private  void MaxHeapIFY(List<T> originList, int heapSie, int pos)
            {
                int len = heapSie;
                int largest = 0;
                int cLeft = pos * 2;
                int cRight = pos * 2 + 1;
                while (cLeft < len || cRight < len)
                {
                    largest = cLeft;
                    if (cRight < len && originList[cLeft].CompareTo(originList[cRight]) < 0)
                    {
                        largest = cRight;
                    }
                    if (originList[pos].CompareTo(originList[largest]) >= 0)
                    {
                        break;
                    }
                    else
                    {
                        Swap(originList, pos, largest);
                        pos = largest;
                        cLeft = pos * 2;
                        cRight = pos * 2 + 1;
                    }
    
                }
            }
    
            private void HeapIncreaseKey(T key, int pos,  bool isInsert = false)
            {
                if (queue.Count <= 0) return;
                if (key.CompareTo(queue[pos]) < 0 && !isInsert) return;
    
                //赋值
                queue[pos] = key;
    
                //维护堆性质
                int parent = Parent(pos);
    
                while (parent >= 0 && queue[pos].CompareTo(queue[parent]) > 0)
                {
                    Swap(queue, pos, parent);
                    pos = parent;
                    parent = Parent(parent);
                }
            }
    
            private int Parent(int pos)
            {
                return pos / 2;
            }
    
    
            /// <summary>
            /// 数组中两个元素交换
            /// </summary>
            private  void Swap(List<T> originList, int posFirst, int posSec)
            {
                T temp = originList[posFirst];
                originList[posFirst] = originList[posSec];
                originList[posSec] = temp;
            }
    
    
        }
    }
  • 相关阅读:
    idea教程--面板介绍
    idea教程--使用mave创建普通java项目
    【Spring】Spring中的Bean
    【Spring】创建一个Spring的入门程序
    【Spring】 Spring的核心容器
    【玩转算法】1、总结,算法思想,加油
    【高级排序算法】3、归并排序法的优化
    【高级排序算法】2、归并排序法的实现-Merge Sort
    【高级排序算法】1、归并排序法
    【排序基础】6、插入排序法的改进与选择排序的效率比较
  • 原文地址:https://www.cnblogs.com/lixiang-share/p/5866698.html
Copyright © 2011-2022 走看看