备注
考虑到 Heap 的特性,很容易想到将其用作排序的用处,为了提高效率需要适当的改进一下,如:in place remove 和 in place move down。
代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DataStuctureStudy.Sorts 8 { 9 class HeapSort<T> 10 where T : IComparable<T> 11 { 12 public static void Test() 13 { 14 var items = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; 15 HeapSort<int>.Sort(items); 16 Console.WriteLine(String.Join(",", items)); 17 } 18 19 public static void Sort(T[] items) 20 { 21 for (int i = items.Length / 2 - 1; i >= 0; i--) 22 { 23 MoveDown(items, i, items.Length - 1); 24 } 25 26 for (var i = items.Length - 1; i >= 0; i--) 27 { 28 items[i] = Remove(items, i); 29 } 30 } 31 32 private static T Remove(T[] items, int endIndex) 33 { 34 var result = items[0]; 35 items[0] = items[endIndex]; 36 37 MoveDown(items, 0, endIndex - 1); 38 39 return result; 40 } 41 42 private static void MoveDown(T[] items, int startIndex, int endIndex) 43 { 44 var top = items[startIndex]; 45 var current = startIndex; 46 47 while (current <= endIndex) 48 { 49 var large = 0; 50 var left = 2 * current + 1; 51 var right = left + 1; 52 53 if (left <= endIndex && right <= endIndex) 54 { 55 if (items[left].CompareTo(items[right]) >= 0) 56 { 57 large = left; 58 } 59 else 60 { 61 large = right; 62 } 63 } 64 else if (left <= endIndex) 65 { 66 large = left; 67 } 68 else 69 { 70 break; 71 } 72 73 if (items[large].CompareTo(top) <= 0) 74 { 75 break; 76 } 77 78 items[current] = items[large]; 79 current = large; 80 } 81 82 items[current] = top; 83 } 84 } 85 }
备注
代码的一部分将未排序数组变为堆,然后将对堆执行 in place remove。