选择排序算法-----堆排序:
堆排序的结构思想就是:先构建(例如大顶堆)然后调整。构建堆,在构建过程中,用到3个变量,root,last,child,其中有两步:比较左右孩子大小,然后将大的值与root比较并且(是否)交换位置。另外,构建完成之后,接着循环将最后一个元素与第一个元素交换位置,然后接着从第一个元素开始,进行调整。
观察下图,数字原始排列为 5,7,3,2,4,8,11,6,1根据上述思想,自行变化。
代码如下:
#include <stdio.h>
void adjustheap(int *a, int root, int last) // 交换调整函数
{
int child ;//定义孩子节点,是用来在调整过程中找到最大值以及判断是否越线
int temp = a[root]; //用临时变量保存一下root的值
for( ; 2*root + 1<=last; root = child) //注意,每次循环root都移动到child的位置
{
child = 2*root+1;
if(child+1 <= last && a[child]<a[child+1])//在不越线的情况下寻找最大值 。
{
child++;
}
if(a[root]<a[child]) //下标root位置的元素与最大值进行交换。
{
a[root] = a[child];
a[child]=temp;
}
}
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b =temp;
}
void heapsort(int *a, int length)
{
//构建大顶堆
int i;
for(i = length/2 - 1; i>=0; i--) //二叉树中,从最后一个非叶节点开始构建
{
adjustheap(a, i, length-1); //调用调整函数,从i到最后一个叶子节点
}
//循环交换根节点与最后叶子节点i的元素值
for(i = length-1; i>0; i--) //每进行一次大根堆的调整就把根节点的值与最后相应的一个节点的值进行交换。
{
swap(&a[0],&a[i]);
adjustheap(a,0,i-1);//交换完之后,再次调用调整函数,注意这里每次都是从0(根节点开始到i-1的叶子节点结束)
}
}
int main()
{
int arry[]={5,7,3,2,4,8,11,1};
int length = sizeof(arry)/sizeof(int);
printf("排序前: ");
for(int i=0; i<length; i++)
{
printf("%d ", arry[i]);
}
heapsort(arry, length);
printf("\n排序后: ");
for(int i=0; i<length; i++)
{
printf("%d ", arry[i]);
}
return 0;
}
程序运行结果: