原理如下:
首先要根据给出的无序的数组构造一个大根堆,步骤如下:
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);
}
}
}
469

被折叠的 条评论
为什么被折叠?



