(1)堆排序为选择排序的一种,适合于大量数据的排序,不稳定的算法,时间复杂度为O(logn);
(2)大根堆为一个完全二叉树,根节点的关键字值大于子节点,整个树的根节点为最大值,用数组表示R[1....n],R[1]为最大,将R[1]和R[n]互换,但此时从1到n-1依然是无序。需要对其进行重新调整处理;
(3)建堆-》取首元素-》调整为大根堆
//堆排序
void HeapSort(int A[], int N)
{
int i;
//步骤一:创建大根堆
for (i = N/2; i>=0; i--)
{
PercDown(A, i, N);
}
//步骤二:调整大根堆
for ( i = N-1; i > 0; i--)
{
//首尾交换
Swap(&A[0], &A[i]);
//元素下沉
PercDown(A, 0, i);
}
}
//交换两个元素的位置
void Swap(int *num1, int * num2)
{
int tmp = *num1;
*num1 = *num2;
*num2 = tmp;
}
构建大根堆
#define LeftChild(i) (2*(i)+1)
//元素下沉方法
void PercDown(int A[], int i, int N)
{
//子节点的索引号
int child;
//存储当前父节点元素的临时变量
//(注:每一个节点都可以看作是其子树的根节点)
int tmp;
for (tmp = A[i]; LeftChild(i)<N; i = child)
{
child = LeftChild(i);
//挑选出左、右子节点中较大者
if (child != N-1 && A[child+1]>A[child])
{
child++;
}
//比较当前父节点与较大子节点
if (A[i]<A[child])
{
//交换当前父节点处的元素值与较大子节点的元素值
tmp= A[i];
A[i] = A[child];
A[child] = tmp;
}
else
{
break;
}
}
}