原理如下:
首先要根据给出的无序的数组构造一个大根堆,步骤如下:
1, 找出第一个非叶子结点的编号,记为根结点root。
2, 找出这个编号的左右孩子结点的编号a, b。
3, 比较这3个结点,找出值最大的那个结点。
4, 如果这个最大的值不是root,那么就赋值给root所在的结点,并且更新root指针为当前的结点编号,同时还要更新左右孩子的编号。
5, 如果这个最大的值是root,说明本次以本root为根的树是一个堆,顾调出循环。
6, 循环调用以上的步骤,找出下一个非叶子结点并构造堆。
然后排序,步骤如下:
1, 只要这个堆当前的长度大于1,就交换第一个和最后一个元素。
2, 交换完了以后要将堆的长度减一,重新更新堆。
代码如下:
class Program { static void Main(string[] args) { int[] array = { 49, 38, 65, 97, 76, 13, 27, 0, 34 }; BuildHeap(array, 9); foreach (int num in array) { Console.Write(num + " ,"); } Console.ReadLine(); } static void AdjustHeap(int[] A, int hlen, int root) { int left = 2 * root + 1; int right = 2 * root + 2; int largest = root; int temp; while (left < hlen || right < hlen) { if (left < hlen && A[largest] < A[left]) largest = left; if (right < hlen && A[largest] < A[right]) largest = right; if (root != largest) //如果最大值不是父节点 { temp = A[largest]; A[largest] = A[root]; A[root] = temp; root = largest; //新的父节点,已备迭代调堆 left = 2 * (root + 1) - 1; right = 2 * (root + 1); } else break; //不必调整 } } static void BuildHeap(int[] A, int hLen) { for (int i = hLen / 2 - 1; i >= 0; i--) { AdjustHeap(A, hLen, i); } while (hLen > 1) { int temp = A[hLen - 1]; A[hLen - 1] = A[0]; A[0] = temp; hLen--; AdjustHeap(A, hLen, 0); } } }