算法 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. namespace CSharpLearning
  23. {
  24. using System;
  25. /// <summary>
  26. /// The program.
  27. /// </summary>
  28. public static class Program
  29. {
  30. /// <summary>
  31. /// 程序入口点。
  32. /// </summary>
  33. public static void Main()
  34. {
  35. int[] a = { 1, 14, 6, 2, 8, 66, 9, 3, 0, 10, 5, 34, 76, 809, 4, 7 };
  36. Console.WriteLine("Before Heap Sort...");
  37. foreach (int i in a)
  38. {
  39. Console.Write(i + " ");
  40. }
  41. Console.WriteLine("\r\n--------------------");
  42. Console.WriteLine("In Heap Sort...");
  43. HeapSort(a);
  44. Console.WriteLine("--------------------");
  45. Console.WriteLine("After Heap Sort...");
  46. foreach (int i in a)
  47. {
  48. Console.Write(i + " ");
  49. }
  50. Console.WriteLine(string.Empty);
  51. }
  52. /// <summary>
  53. /// 堆排序方法。
  54. /// </summary>
  55. /// <param name="a">
  56. /// 待排序数组。
  57. /// </param>
  58. private static void HeapSort(int[] a)
  59. {
  60. BuildMaxHeap(a); // 建立大根堆。
  61. Console.WriteLine("Build max heap:");
  62. foreach (int i in a)
  63. {
  64. Console.Write(i + " "); // 打印大根堆。
  65. }
  66. Console.WriteLine("\r\nMax heap in each iteration:");
  67. for (int i = a.Length - 1; i > 0; i--)
  68. {
  69. Swap(ref a[0], ref a[i]); // 将堆顶元素和无序区的最后一个元素交换。
  70. MaxHeaping(a, 0, i); // 将新的无序区调整为大根堆。
  71. // 打印每一次堆排序迭代后的大根堆。
  72. for (int j = 0; j < i; j++)
  73. {
  74. Console.Write(a[j] + " ");
  75. }
  76. Console.WriteLine(string.Empty);
  77. }
  78. }
  79. /// <summary>
  80. /// 由底向上建堆。由全然二叉树的性质可知,叶子结点是从index=a.Length/2開始。所以从index=(a.Length/2)-1结点開始由底向上进行大根堆的调整。
  81. /// </summary>
  82. /// <param name="a">
  83. /// 待排序数组。
  84. /// </param>
  85. private static void BuildMaxHeap(int[] a)
  86. {
  87. for (int i = (a.Length / 2) - 1; i >= 0; i--)
  88. {
  89. MaxHeaping(a, i, a.Length);
  90. }
  91. }
  92. /// <summary>
  93. /// 将指定的结点调整为堆。
  94. /// </summary>
  95. /// <param name="a">
  96. /// 待排序数组。
  97. /// </param>
  98. /// <param name="i">
  99. /// 须要调整的结点。
  100. /// </param>
  101. /// <param name="heapSize">
  102. /// 堆的大小,也指数组中无序区的长度。
  103. /// </param>
  104. private static void MaxHeaping(int[] a, int i, int heapSize)
  105. {
  106. int left = (2 * i) + 1; // 左子结点。
  107. int right = 2 * (i + 1); // 右子结点。
  108. int large = i; // 暂时变量,存放大的结点值。
  109. // 比較左子结点。
  110. if (left < heapSize && a[left] > a[large])
  111. {
  112. large = left;
  113. }
  114. // 比較右子结点。
  115. if (right < heapSize && a[right] > a[large])
  116. {
  117. large = right;
  118. }
  119. // 如有子结点大于自身就交换,使大的元素上移;而且把该大的元素调整为堆以保证堆的性质。
  120. if (i != large)
  121. {
  122. Swap(ref a[i], ref a[large]);
  123. MaxHeaping(a, large, heapSize);
  124. }
  125. }
  126. /// <summary>
  127. /// 交换两个整数的值。
  128. /// </summary>
  129. /// <param name="a">整数a。</param>
  130. /// <param name="b">整数b。

    </param>
  131. private static void Swap(ref int a, ref int b)
  132. {
  133. int tmp = a;
  134. a = b;
  135. b = tmp;
  136. }
  137. }
  138. }
  139. // Output:
  140. /*
  141. Before Heap Sort...
  142. 1 14 6 2 8 66 9 3 0 10 5 34 76 809 4 7
  143. --------------------
  144. In Heap Sort...
  145. Build max heap:
  146. 809 14 76 7 10 66 9 3 0 8 5 34 1 6 4 2
  147. Max heap in each iteration:
  148. 76 14 66 7 10 34 9 3 0 8 5 2 1 6 4
  149. 66 14 34 7 10 4 9 3 0 8 5 2 1 6
  150. 34 14 9 7 10 4 6 3 0 8 5 2 1
  151. 14 10 9 7 8 4 6 3 0 1 5 2
  152. 10 8 9 7 5 4 6 3 0 1 2
  153. 9 8 6 7 5 4 2 3 0 1
  154. 8 7 6 3 5 4 2 1 0
  155. 7 5 6 3 0 4 2 1
  156. 6 5 4 3 0 1 2
  157. 5 3 4 2 0 1
  158. 4 3 1 2 0
  159. 3 2 1 0
  160. 2 0 1
  161. 1 0
  162. 0
  163. --------------------
  164. After Heap Sort...
  165. 0 1 2 3 4 5 6 7 8 9 10 14 34 66 76 809
  166. */
时间: 2024-10-13 20:44:35

算法 Heap sort的相关文章

经典排序算法 - 堆排序Heap sort

经典排序算法 - 堆排序Heap sort 堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么

排序算法:heap sort(含heap介绍,python)

heap介绍 binary heap可以被看成是一种接近完成的binary tree.可以分为max-heap和min-heap,max-heap的parent要比children大,min-heap相反. 通常用array A构成的heap中,有两个基本的特性:1. A.length,给出了阵列中的元素个数.2. A.heap-size,给出阵列中在heap中的元素. 这两者的区别是,A.heap-size中的才是在heap里的,A.length的长度可能还包含了其他的很多元素. 这个可以在之

算法分析-堆排序 Heap Sort

堆排序的是集合了插入排序的单数组操作,又有归并排序的时间复杂度,完美的结合了2者的优点. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终

Bubble, Insertion, Selection, Quick and Heap Sort

Bubble, Insertion, Selection, Quick and Heap Sort Bubble Sort 冒泡排序是基本的排序算法之一,时间复杂度为,空间复杂度也为.该算法不常被使用,因为和插入排序相比较,插入排序的时间复杂度为,而空间复杂度为.属于稳定排序. 有三种方法可以改进Bubble Sort,①当一轮比较却没有发生交换时,认为数据已经有序,停止排序.②当进行i轮排序后,数据序列后的N-i个元素已经有序,可以不考虑.③假设Data[i]与Data[i+1]是发生的最后一

堆排序(Heap Sort)的C语言实现

堆排序(Heap Sort)具体步骤为 将无序序列建成大顶堆(小顶堆):从最后一个非叶子节点开始通过堆调整HeapAdjust()变成小顶堆或大顶堆 将顶部元素与堆尾数组交换,此是末尾元素就是最大值,顶部元素不满足堆,故要将顶部元素在剩余的i-1个元素中调整为堆 反复第2步.直至所有顶点被输出,序列变成从小到大的有序序列 C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 1

堆排序 Heap Sort

堆排序是一种选择排序,其时间复杂度为O(nlogn). 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆) 情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆) 其中i=1,2,…,n/2向下取整; 若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左

Heap Sort (堆排序)

Heap sort is common in written exams. First of all, what is heap? Heap is a kind of data struct that can be seen as a complete binary tree. The object to indicate heap is an array A that have two attributes: length[A] shows the number of elements in

PAT甲题题解1098. Insertion or Heap Sort (25)-(插入排序和堆排序)

题目就是给两个序列,第一个是排序前的,第二个是排序中的,判断它是采用插入排序还是堆排序,并且输出下一次操作后的序列. 插入排序的特点就是,前面是从小到大排列的,后面就与原序列相同. 堆排序的特点就是,后面是从小到大排列的最大的几个数p~n-1,前面第一位则是p-1. 所以只要先按照插入排序的特点来判断是否为插入排序,接下来再进行操作就可以了,这里要手动写下最大堆的更新操作. 代码: #include <iostream> #include <cstdio> #include <

PAT (Advanced Level) 1098. Insertion or Heap Sort (25)

简单题.判断一下是插排还是堆排. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<queue> #include<stack> #include<algorithm> using namespace std; const int maxn=200; int a[maxn],b[m