堆排序算法及其实现

大一课设题目,看吴zh老师笔记有感。。。。。。。

1.堆的定义:堆实际上是一棵完全二叉树,需要非叶节点满足的以下性质:

a[i]>=a[i*2]&&a[i]>=a[i*2+1](大根堆)

a[i]<=a[i*2]&&a[i]<=a[i*2+1](小根堆)

通俗来讲就是父节点一定大于等于其子节点或者小于等于其子节点。。。。

2.堆排序:一种树形选择排序方法。

特点:将a[1...n]看成是一棵完全二叉树的顺序存储结构。

时间复杂度:O(nlog₂n)

因为题目要求是从小到大,所以可以使用大根堆(若相反则可以使用小根堆)。

(1)数组有n个数,先将这个数组建树,也就是建大根堆,此时a[1]为所有元素的最大值。

(2)将a[1]和a[n]交换值,此时a[1~n-1]为无序,a[n]为有序数列。

(3)然后再将a[1]~a[n-1]进行调整堆,再将a[1]和a[n-1]进行交换值,此时a[n-1]和a[n]为有序,重复此操作就可将数组完整排完。

附上代码:

 1 #include <stdio.h>
 2 void swap(int a[],int x,int y)//交换数组值
 3 {
 4     int temp=a[x];
 5     a[x]=a[y];
 6     a[y]=temp;
 7 }
 8 void heapadjust(int a[],int i,int n)//调整整个树
 9 {
10     int lchild=2*i;//左子节点
11     int rchild=2*i+1;//右子节点
12     int max=i;//先存下此时父节点
13     if(i<=n/2)//将父节点不是非叶节点排除
14     {
15         if(lchild<=n&&a[lchild]>a[max])
16             max=lchild;
17         if(rchild<=n&&a[rchild]>a[max])
18             max=rchild;
19         if(max!=i)//若最大值并不是父节点
20         {
21             swap(a,max,i);
22             heapadjust(a,max,n);//需要再调整以max为父节点的子树为堆
23         }
24     }
25 }
26 void heapbuild(int a[],int n)//建堆
27 {
28     int i;
29     for(i=n/2;i>=1;i--)//每次的调整需要从非叶节点,若有两个子节点则调整这三个数
30     {
31         heapadjust(a,i,n);
32     }
33 }
34 void heapsort(int a[],int n)//堆排序
35 {
36     int i;
37     heapbuild(a,n);
38     for(i=n;i>1;i--)//进行n-1趟完成堆排序,每一趟堆中元素个数减一
39     {
40         swap(a,1,i);
41         heapadjust(a,1,i-1);
42     }
43 }
44 int main(void)
45 {
46     int size,a[10],i;
47     printf("请输入排序个数,且个数小于10:");
48     scanf("%d",&size);
49     printf("请输入%d个数字,以空格隔开:",size);
50     for(i=1;i<=size;i++)
51         scanf("%d",&a[i]);
52     heapsort(a,size);
53     printf("排序后:");
54     for(i=1;i<=size;i++)
55         printf("%d ",a[i]);
56     printf("\n");
57     return 0;
58 }

——————————————————————————-——————————————————————

Manba out ??

Not,Manba forever!

posted @ 2020-04-27 15:34  头巨铁  阅读(426)  评论(2编辑  收藏  举报