堆排序

一、堆排序

①最大堆的堆顶是整个堆中的最大元素。

②最小堆的堆顶是整个堆中的最小元素

注意:如果删除一个最大堆的堆顶(则并不是完全删除,而是跟末尾的节点交换位置),经过自我调整,第二大的元素就会被交换上来,成为最大的堆顶。

③二叉堆实际存储在数组中。

二、堆排序的步骤

①把无序的数组构建成为二叉堆【需要从小到大排序,则构建成最大堆;需要从大到小排序,则构建成最小堆】

②循环删除堆顶元素,替换到二叉堆的末尾,调整堆产生新的堆顶。

三、堆排序的核心

/***
*	Title:  "算法" 项目
*	主题 : 堆排序
*	Description: 
*	功能 : 
*	Date:  2020-07-04
*	Version:  1.2
*	Author:  Coffee
*	Modify Recoder:  
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kernal
{
    class HeapSort
    {

        //最大堆排序(升序)
        public static void MaxHeapSort(int[] array)
        {
            //1、把无序数组构建成最大堆
            int len = array.Length;
            //右孩子索引
            int rightChildIndex=(len-2)/2;
            for (int i = rightChildIndex; i >=0 ; i--)
            {
                DownAdjust(array,i,len);
            }
            Console.WriteLine("最大堆如下:");
            Display(array);

            Console.WriteLine("\n升序:");
            //2、循环删除堆顶元素,移到集合尾部,调整产生新的堆顶
            for (int i = len - 1; i >= 0; i--)
            {
                //最后一个元素与第一个元素交换
                int tmp = array[i];
                array[i] = array[0];
                array[0] = tmp;

                //下沉调整最大堆
                DownAdjust(array, 0, i);
            }

        }


        /// 
        /// 下沉调整
        /// 
        /// 待调整的堆
        /// 要“下沉”的父节点
        /// 堆的有效大小
        private static void DownAdjust(int[] array,int parentIndex,int length)
        {
            //tmp保存父节点值,用于最后赋值
            int tmp = array[parentIndex];
            //左孩子节点索引
            int childIndex = 2 * parentIndex + 1;

            while (childIndexarray[childIndex])
                {
                    childIndex++;
                }
                //如果父节点大于任何一个孩子的值,则直接跳出
                if (tmp>array[childIndex])
                {
                    break;
                }
                //无需真正交换,单向赋值即可
                array[parentIndex] = array[childIndex];
                parentIndex = childIndex;
                childIndex = 2 * childIndex + 1;

            }

            array[parentIndex] = tmp;
        }

     
        //显示结果
        private static void Display(int[] array)
        {
            string str = null;
            foreach (var item in array)
            {
                str += item + " ";
            }
            Console.WriteLine(str);
        }



    }//Class_end

}

四、使用方法

①、引用命名空间:using Kernal;

②、HeapSort+方法名称;

③、在方法中传入列表即可。

五、示例

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Kernal;

namespace CommonSort
{
    class Program
    {
        static void Main(string[] args)
        {
            //时间计时器
            Stopwatch _SW = new Stopwatch();


            Console.WriteLine("原数组为:");
            int[] array = {69, 25, 78, 1, 56, 24, 98, 71, 2, 6, 1, 5, 8, 9};
            int[] array2 = { 69, 25, 78, 1, 56, 24, 98, 71, 2, 6, 1, 5, 8, 9 };
            Display(array);

            Console.WriteLine("\n--------------- 堆排序(最大堆升序)----------------------");
            _SW.Start();
            Console.WriteLine(" 堆排序(最大堆)为:");
            HeapSort.MaxHeapSort(array);
            Display(array);
            _SW.Stop();
            Console.WriteLine("花费时间为:{0} 毫秒",_SW.Elapsed.TotalMilliseconds);

          



            Console.Read();
        }//Main_end



        //显示结果
        private static void Display(int[] array)
        {
            string str = null;
            foreach (var item in array)
            {
                str += item + " ";
            }
            Console.WriteLine(str);
        }

    }//Class_end
}

六、运行结果

 堆排序_第1张图片

 

 

 

 

 

 

 

你可能感兴趣的:(算法)