C# 堆排序
using System; using System.Collections; namespace Sort { public class HeapSorter { public static int[] 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); // 将新的无序区调整为堆,无序区在变小 } return sortArray; } /// <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; } } }
堆排序的想法:
利用大頂堆(小頂堆)堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。
其基本思想為(大頂堆):
1)將初始待排序關鍵字序列(R1,R2....Rn)建構成大頂堆,此堆為初始的無序區;
2)將堆頂元素R[1]與最後一個元素R[n]交換,此時得到新的無序區(R1,R2,......Rn-1)和新的有序區( Rn),且滿足R[1,2...n-1]
3)由於交換後新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,......Rn-1)調整為新堆,然後再次將R[1]與無序區最後一個元素交換,得到新的無序區(R1,R2.. ..Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數為n-1,則整個排序過程完成。
操作過程如下:
1)初始化堆:將R[1..n]構造為堆;
2)將目前無序區的堆頂元素R[1]同該區間的最後一個記錄交換,然後將新的無序區調整為新的堆。
因此對於堆排序,最重要的兩個操作就是構造初始堆和調整堆,其實構造初始堆事實上也是調整堆的過程,只不過構造初始堆是對所有的非葉節點都進行調整。
以上就是C# 堆排序的內容,更多相關內容請關注PHP中文網(www.php.cn)!