数据结构排序算法——堆排序

/ *我们讲到了第六个排序了。就是堆排序。
首先我们要清楚什么是堆。堆有大顶堆和小顶堆(这里不知道什么是大顶堆个小顶堆,不要着急。一会会说清楚的 )。
我们要的是从小到大排序,所以我们要的是大顶堆。
大顶堆就是。我们把一维数组看成一棵树。根节点为a[i].左右孩子分别为a[2*i]和a[2*i+1];
当我们规定a>=a[2*i]同时a>=a[2*i+1]。的时候,这时候就为大顶堆。
相反的。小顶堆就不用解释了,
我们的算法思路是?
假设有10元素a[1]~a[10]
首先要建立一个原初始堆。此时满足对的定义,堆顶的元素最大,a[1]最大,
接着就是重点思想了。我们我们把根节点a[1]与末尾元素a[10]交换后,此时a[10]就是就是最大元素。
接着我们在剩下的a[1]~a[9]在进行堆排序,使得a[1]是根节点再次是最大值,接着与a[9]交换,a[9]变成了继a[10]之后的最大值。
一次类推,剩下一个根节点的时候,说明这时候这个根节点最小了。
但是我们要明白的是如何进行堆排序呢?
如何对进行对原初始堆?这是两个要思考的重点!
假设,我们先进行了原初始堆。接着将堆顶与堆末尾的元素交换后,此时要保存根节点temp=a[1]的值,我们a[1]与a[2],a[3]肯定不符合堆的定义了。
但是在原始堆的前提下,以a[2],a[3]分别为根节点的堆满足定义,所以,我们就是比较a[2]与a[3]最大值,
与根节点交换,a[1]有了最大值,但是a[2]与a[3]交换可能有一个堆不满足堆的定义,接着我们再用temp与不满足根节点的左右孩子进行比较,交换。。
。。。我们还是上代码把,*/
#include <stdio.h>
void adjust(int *a,int,int);//进行堆排序
int main(void)
{
int a[11],i,temp,n=10;
printf("请输入10 个数:");
for(i=1;i<=10;i++)
scanf("%d",a+i);
for(i=n/2;i>=1;i--)
adjust(a,i,n);
for(i=n;i>=2;i--)
{
temp=a[i];
a[i]=a[1];
a[1]=temp;
adjust(a,1,i-1);
}
for(i=1;i<=10;i++)
printf("%3d",a[i]);
printf("\n");
return 0;
}
void adjust(int *a,int i,int n)
{

int j=2*i,temp=a[i];
while(j<=n)
{
if(j<n&&a[j]<a[j+1])//如果存在右子树的话,而且右子树小于左子树的话
j++;//这时候a[j]为左右子树里最大的数
if(temp>a[j])//如果根节点大于最大的数,已经成了堆。
break;
else
{
a[j/2]=a[j];//将根节点赋值为左右子树最大的值。
j*=2;//这样做的目的就是,j为下一次的左右子树
}
}
a[j/2]=temp;
return ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值