• 算法 Heap sort


    1. // --------------------------------------------------------------------------------------------------------------------  
    2. // <copyright file="Program.cs" company="Chimomo's Company">  
    3. //  
    4. // Respect the work.  
    5. //  
    6. // </copyright>  
    7. // <summary>  
    8. //  
    9. // Heap sort.  
    10. //  
    11. // 堆排序是一种选择排序,时间复杂度为O(nlog<sub>2</sub>n)。  
    12. // 堆排序的特点是:在排序过程中,将待排序数组看成是一棵全然二叉树的顺序存储结构,利用全然二叉树中父结点和子结点之间的内在关系,在当前无序区中选择keyword最大(或最小)的记录。

        

    13. //  
    14. // 基本思想  
    15. // 1.将待排序数组调整为一个大根堆。大根堆的堆顶元素就是这个堆中最大的元素。  
    16. // 2.将大根堆的堆顶元素和无序区最后一个元素交换,并将无序区最后一个位置列入有序区,然后将新的无序区调整为大根堆。  
    17. // 3.反复操作,直到无序区消失为止。  
    18. // 初始时,整个数组为无序区。每一次交换,都是将大根堆的堆顶元素换入有序区,以保证有序区是有序的。

        

    19. //  
    20. // </summary>  
    21. // --------------------------------------------------------------------------------------------------------------------  
    22.   
    23. namespace CSharpLearning  
    24. {  
    25.     using System;  
    26.   
    27.     /// <summary>  
    28.     /// The program.  
    29.     /// </summary>  
    30.     public static class Program  
    31.     {  
    32.         /// <summary>  
    33.         /// 程序入口点。  
    34.         /// </summary>  
    35.         public static void Main()  
    36.         {  
    37.             int[] a = { 1, 14, 6, 2, 8, 66, 9, 3, 0, 10, 5, 34, 76, 809, 4, 7 };  
    38.             Console.WriteLine("Before Heap Sort...");  
    39.             foreach (int i in a)  
    40.             {  
    41.                 Console.Write(i + " ");  
    42.             }  
    43.   
    44.             Console.WriteLine(" --------------------");  
    45.             Console.WriteLine("In Heap Sort...");  
    46.             HeapSort(a);  
    47.             Console.WriteLine("--------------------");  
    48.             Console.WriteLine("After Heap Sort...");  
    49.             foreach (int i in a)  
    50.             {  
    51.                 Console.Write(i + " ");  
    52.             }  
    53.   
    54.             Console.WriteLine(string.Empty);  
    55.         }  
    56.   
    57.         /// <summary>  
    58.         /// 堆排序方法。  
    59.         /// </summary>  
    60.         /// <param name="a">  
    61.         /// 待排序数组。

        

    62.         /// </param>  
    63.         private static void HeapSort(int[] a)  
    64.         {  
    65.             BuildMaxHeap(a); // 建立大根堆。  
    66.             Console.WriteLine("Build max heap:");  
    67.             foreach (int i in a)  
    68.             {  
    69.                 Console.Write(i + " "); // 打印大根堆。  
    70.             }  
    71.   
    72.             Console.WriteLine(" Max heap in each iteration:");  
    73.             for (int i = a.Length - 1; i > 0; i--)  
    74.             {  
    75.                 Swap(ref a[0], ref a[i]); // 将堆顶元素和无序区的最后一个元素交换。  
    76.                 MaxHeaping(a, 0, i); // 将新的无序区调整为大根堆。  
    77.   
    78.                 // 打印每一次堆排序迭代后的大根堆。  
    79.                 for (int j = 0; j < i; j++)  
    80.                 {  
    81.                     Console.Write(a[j] + " ");  
    82.                 }  
    83.   
    84.                 Console.WriteLine(string.Empty);  
    85.             }  
    86.         }  
    87.   
    88.         /// <summary>  
    89.         /// 由底向上建堆。由全然二叉树的性质可知,叶子结点是从index=a.Length/2開始。所以从index=(a.Length/2)-1结点開始由底向上进行大根堆的调整。  
    90.         /// </summary>  
    91.         /// <param name="a">  
    92.         /// 待排序数组。  
    93.         /// </param>  
    94.         private static void BuildMaxHeap(int[] a)  
    95.         {  
    96.             for (int i = (a.Length / 2) - 1; i >= 0; i--)  
    97.             {  
    98.                 MaxHeaping(a, i, a.Length);  
    99.             }  
    100.         }  
    101.   
    102.         /// <summary>  
    103.         /// 将指定的结点调整为堆。

        

    104.         /// </summary>  
    105.         /// <param name="a">  
    106.         /// 待排序数组。

        

    107.         /// </param>  
    108.         /// <param name="i">  
    109.         /// 须要调整的结点。

        

    110.         /// </param>  
    111.         /// <param name="heapSize">  
    112.         /// 堆的大小,也指数组中无序区的长度。  
    113.         /// </param>  
    114.         private static void MaxHeaping(int[] a, int i, int heapSize)  
    115.         {  
    116.             int left = (2 * i) + 1; // 左子结点。

        

    117.             int right = 2 * (i + 1); // 右子结点。  
    118.             int large = i; // 暂时变量,存放大的结点值。  
    119.   
    120.             // 比較左子结点。  
    121.             if (left < heapSize && a[left] > a[large])  
    122.             {  
    123.                 large = left;  
    124.             }  
    125.   
    126.             // 比較右子结点。

        

    127.             if (right < heapSize && a[right] > a[large])  
    128.             {  
    129.                 large = right;  
    130.             }  
    131.   
    132.             // 如有子结点大于自身就交换,使大的元素上移;而且把该大的元素调整为堆以保证堆的性质。

        

    133.             if (i != large)  
    134.             {  
    135.                 Swap(ref a[i], ref a[large]);  
    136.                 MaxHeaping(a, large, heapSize);  
    137.             }  
    138.         }  
    139.   
    140.         /// <summary>  
    141.         /// 交换两个整数的值。  
    142.         /// </summary>  
    143.         /// <param name="a">整数a。</param>  
    144.         /// <param name="b">整数b。

      </param>  

    145.         private static void Swap(ref int a, ref int b)  
    146.         {  
    147.             int tmp = a;  
    148.             a = b;  
    149.             b = tmp;  
    150.         }  
    151.     }  
    152. }  
    153.   
    154. // Output:  
    155. /* 
    156. Before Heap Sort... 
    157. 1 14 6 2 8 66 9 3 0 10 5 34 76 809 4 7 
    158. -------------------- 
    159. In Heap Sort... 
    160. Build max heap: 
    161. 809 14 76 7 10 66 9 3 0 8 5 34 1 6 4 2 
    162. Max heap in each iteration: 
    163. 76 14 66 7 10 34 9 3 0 8 5 2 1 6 4 
    164. 66 14 34 7 10 4 9 3 0 8 5 2 1 6 
    165. 34 14 9 7 10 4 6 3 0 8 5 2 1 
    166. 14 10 9 7 8 4 6 3 0 1 5 2 
    167. 10 8 9 7 5 4 6 3 0 1 2 
    168. 9 8 6 7 5 4 2 3 0 1 
    169. 8 7 6 3 5 4 2 1 0 
    170. 7 5 6 3 0 4 2 1 
    171. 6 5 4 3 0 1 2 
    172. 5 3 4 2 0 1 
    173. 4 3 1 2 0 
    174. 3 2 1 0 
    175. 2 0 1 
    176. 1 0 
    177. 0 
    178. -------------------- 
    179. After Heap Sort... 
    180. 0 1 2 3 4 5 6 7 8 9 10 14 34 66 76 809 
    181. */  
  • 相关阅读:
    数据结构笔记
    并查集
    计算两个数的最大公约数和最小公倍数
    行盒
    浏览器兼容性和布局
    Java中HashMap等的实现要点浅析
    关于js异步上传文件
    填充路径时所使用的 “非零环绕规则”
    XP极限编程
    假如森林里有一棵树倒下了
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6785920.html
Copyright © 2020-2023  润新知