堆排序利用二叉树模型,把要排序的元素建成一个类似完全二叉树的样子,将每三个元素中最大的元素调整至这三个结点中根结点的位置,调整后最大元素位于整个树的根结点位置。将根结点的元素与最后一个元素交换,则最大数沉底,将树的长度减一,调整结点位置,重复操作,最后得到排好序的数组。
堆排序是不稳定排序。
以下为代码演示
void Swap(int *a, int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
void printA(int *a,int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%4d",a[i]);
}
printf("\n");
}
void heapify(int *a, int i, int len)
{
int left = 2*i+1; //左孩子结点下标
int right = 2*i+2; //右孩子结点下标
int max = i; //三个结点中最大元素的下标
if(left < len && a[left] > a[max])
max = left;
if(right < len && a[right] > a[max])
max = right;
if(max != i) //当父节点不是三个结点中最大的元素要进行调整
{
Swap(a, i, max);
heapify(a, max, len); //调整被交换的结点
}
}
void heapSort(int *a, int len)
{
int i;
//建堆
for(i = 0; i < len; i++)
{
heapify(a, i, len);
}
for(i = len-1; i > 0; i--)
{
Swap(a, 0, i); //拿堆顶元素与堆尾元素交换
len--; //找到一个最大元素以后堆大小减一
heapify(a, 0, len); //调整堆顶元素
}
}
int main()
{
int a[10] = {7,2,9,4,1,3,8,6,5,0};
int len = sizeof(a)/sizeof(a[0]);
heapSort(a,len);
printA(a,len);
return 0;
}