数据结构中的堆

Posted 久光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构中的堆相关的知识,希望对你有一定的参考价值。

一:堆排序

     堆排序(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("==================");

        }
    }
}

以上是关于数据结构中的堆的主要内容,如果未能解决你的问题,请参考以下文章

JVM中的堆和非堆内存

java中的堆和栈

里常说的堆,栈,堆栈到底是什么,从os的角度总结

.NET中的堆(Heap)和栈(Stack)的本质

值类型和引用类型的区别 I 数据结构中的堆和栈和内存中的堆和栈的区别

关于内存类型中的堆