前言
堆排序的效率在各种排序中也是比较高的效率了,时间复杂度为O(nlog2n)
一、堆排序实现
实现堆排序首先我们要先建堆,而排序有升序和降序;
要排 升序我们要建大堆要排降序我们要建小堆
升序建大堆的原因是根节点是最大的,每次我们让最后一个与根进行转换,这时我们的堆改变了,最后一个变成最大数了,这时我们忽略最后一个最大数对堆进行调整,再次变成大堆,依次操作我们就可以得到一个升序的堆;
降序道理差不多;
如何建堆:
我们要知道,建堆实际上是对数组进行处理并不是真正意义上的建堆。
如我们有这样一个数组:
int a[] = {15,1,19,25,8,34,65,4,27,7};
我们用向下调整建堆—就是找最后一个不是叶子节点的节点与其子节点进行比较,看情况进行转换,建大堆让这个节点与其孩子节点最大的进行转换,建小堆就让这个节点与其孩子节点最小的进行转换;
if (minchilen + 1 < n && p[minchilen] < p[minchilen + 1])
{
minchilen++;
}
if (p[parent] < p[minchilen])
{
swap(&p[parent], &p[minchilen]);
parent = minchilen;
minchilen = parent * 2 + 1;
}
这里我们让两个孩子节点进行比较,让大的与节点进行比较,建的是大堆
此时我们通过调试发现堆已经建好了;
然后根据上面提供的思路我们转换最后一个节点和根节点进行排序
int i = 1;
while (i < n)
{
swap(&a[0], &a[n - i]);
Adjustdown(a, n - i, 0);
i++;
}
二、具体代码
#include<stdio.h>
void Adjustdown(int* p, int n, int parent)
{
int minchilen = parent * 2 + 1;
while (minchilen < n)
{
if (minchilen + 1 < n && p[minchilen] < p[minchilen + 1])
{
minchilen++;
}
if (p[parent] < p[minchilen])
{
swap(&p[parent], &p[minchilen]);
parent = minchilen;
minchilen = parent * 2 + 1;
}
else
break;
}
}
void swap(piledata* a, piledata* b)
{
piledata tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a[] = {15,1,19,25,8,34,65,4,27,7};
int n = sizeof(a)/sizeof(a[0]);
for (int i = (n - 1 - 1) / 2;i>=0; i--)
{
Adjustdown(a,n,i);
}
int i = 1;
while (i < n)
{
swap(&a[0], &a[n - i]);
Adjustdown(a, n - i, 0);
i++;
}
return 0;
}