zoukankan      html  css  js  c++  java
  • 堆排序

    堆排序
    堆排序是一种选择排序。是不稳定的排序方法。时间复杂度为O(nlog2n)。
    堆排序的特点是:在排序过程中,将排序数组看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子节点之间的内在关系,在当前无序区中选择关键字最大(或最小)的记录。

    基本思想
    1.将要排序的数组创建为一个大根堆。大根堆的堆顶元素就是这个堆中最大的元素。
    2.将大根堆的堆顶元素和无序区最后一个元素交换,并将无序区最后一个位置例入有序区,然后将新的无序区调整为大根堆。
    重复操作,无序区在递减,有序区在递增。
    初始时,整个数组为无序区,第一次交换后无序区减一,有序区增一。
    每一次交换,都是大根堆的堆顶元素插入有序区,所以有序区保持是有序的。

    大根堆和小根堆
    堆:是一颗完全二叉树。
    大根堆:所有节点的子节点比其自身小的堆
    小根堆:所有节点的子节点比其自身大的堆

    完全二叉树的基本性质
    数组中有n个元素,i是节点
    1 <= i <= n/2 就是说数组的后一半元素都是叶子节点。
    i的父节点位置:i/2
    i左子节点位置:i*2
    i右子节点位置:i*2 + 1

    如一个数组
    物理结构:15 20 35 25 30 40 50

    逻辑结构:
        15
       /  
      20    35
    /    /
    25 30 40 50
    这是一个小根堆,所有节点的子节点比其自身大。15,20,35是节点,其它的都是叶子。

    由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。

    例子

    using System;
    using System.Collections;
    
    
    namespace System
    {
        public class Test
        {
            public static void Main()
            {
                int[] array = new int[6] { 40, 10, 20, 15, 35, 20 };
    
                HeapSort.Sort(array);
    
                PrintArray(array);
                Console.ReadKey();
            }
    
            public static void PrintArray(int[] array)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    if (i > 0) Console.Write(" ");
                    Console.Write(array[i].ToString());
                }
                Console.WriteLine();
            }
        }
    
        public class HeapSort
        {
            public static void Sort(int[] sortArray)
            {
                BuildMaxHeap(sortArray);
                for (int i = (sortArray.Length - 1); i > 0; i--)
                {
                    Swap(ref sortArray[0], ref sortArray[i]); // 将堆顶元素和无序区的最后一个元素交换
                    MaxHeapify(sortArray, 0, i); // 将新的无序区调整为堆,无序区在变小
                }
            }
    
            /// <summary>
            /// 初始大根堆,自底向上地建堆
            /// 完全二叉树的基本性质,最底层节点是 n/2,所以从 sortArray.Length / 2 开始
            /// </summary>
            private static void BuildMaxHeap(int[] sortArray)
            {
                for (int i = (sortArray.Length / 2) - 1; i >= 0; i--)
                {
                    MaxHeapify(sortArray, i, sortArray.Length);
                }
            }
    
    
            /// <summary>
            /// 将指定的节点调整为堆
            /// </summary>
            /// <param name="i">需要调整的节点</param>
            /// <param name="heapSize">堆的大小,也指数组中无序区的长度</param>
            private static void MaxHeapify(int[] sortArray, int i, int heapSize)
            {
                int left = 2 * i + 1; // 左子节点
                int right = 2 * i + 2; // 右子节点
                int larger = i; // 临时变量,存放大的节点值
    
                // 比较左子节点
                if (left < heapSize && sortArray[left] > sortArray[larger])
                {
                    larger = left;
                }
    
                // 比较右子节点
                if (right < heapSize && sortArray[right] > sortArray[larger])
                {
                    larger = right;
                }
    
                // 如有子节点大于自身就交换,使大的元素上移。
                if (i != larger)
                {
                    Swap(ref sortArray[i], ref sortArray[larger]);
                    MaxHeapify(sortArray, larger, heapSize);
                }
            }
    
            private static void Swap(ref int a, ref int b)
            {
                int t;
                t = a;
                a = b;
                b = t;
            }
        }
    }
    
  • 相关阅读:
    kubernetes之常见故障排除(一)
    kubernetes集群管理命令(三)
    kubernetes集群管理命令(二)
    kubernetes集群管理常用命令一
    kubernetes集群管理之通过jq来截取属性
    kubernetes管理之使用yq工具截取属性
    kubectl技巧之通过jsonpath截取属性
    kubectl技巧之通过go-template截取属性
    kubernetes容器编排之定义环境变量以及通过downwardapi把pod信息作为环境变量传入容器内
    kubectl技巧之查看资源列表,资源版本和资源schema配置
  • 原文地址:https://www.cnblogs.com/kidfruit/p/1692837.html
Copyright © 2011-2022 走看看