二叉树之堆排序

堆排序,首先要对堆的性质有了解,分大顶堆和小顶堆,我这次写的是大顶堆,即父节点大于其子节点,在把堆无序后,从堆顶开始遍历,得到大堆顶,把堆顶与最后一个元素对换,这时,最后一个元素就是最大值,这时,就不用考虑最后一个元素了,开始循环。重新开始从头遍历,详细过程写在代码里,大家参考:

图片:


/*此排序主要有2个难点,第一个是初始化无序堆,第二个是交换元素形成有序堆

写的是大顶堆

1.首先要从下三角开始遍历,一层层的往前推,推到a[0],此时的a[0]是最大值。这时,此堆已经初始成功
2.a[0]即为最大顶,把a[0]与最后一个元素a[len-1]交换,就不用考虑最后一个值了,但是这时的堆已经不符合
性质了。
3.因此开始从a[0]往下支路换,换到a[0]为 0--len-1 最大值,交换 a[0]和a[len-2]的值,这时,a[len-2]和a[len-1]
为有序的。
4.不断循环,直到a[1]排好序,a[0]就不用排了。*/

#include<stdio.h>
//从下三角开始交换得到最大堆
void adjustMaxHeap(int a[], int len, int parentNodeIndex) 
{
	// 记录比父节点大的左孩子或者右孩子的索引
	 int targetIndex = -1;
	// 获取左、右孩子的索引
	 int leftChildIndex = 2 * parentNodeIndex + 1;
	 int rightChildIndex = 2 * parentNodeIndex + 2;
	//如果没有子节点,就返回
	 if(leftChildIndex>=len)
	 {
		 return;
	 }
	 //有左节点,没有右节点
	 if(rightChildIndex>=len)
	 {
		 targetIndex=leftChildIndex;
	 }
	//有左节点,有右节点
	 else{
		 targetIndex=(a[leftChildIndex] > a[rightChildIndex])?leftChildIndex:rightChildIndex;
	 }
	 //进行比较和互换
	 if(a[targetIndex]>a[parentNodeIndex])
	 {
		 int tmp;
		 tmp=a[targetIndex];
		 a[targetIndex]=a[parentNodeIndex];
		 a[parentNodeIndex]=tmp;
		 //在初始化堆时,用不到下边的语句,在从上往下遍历时,这个语句是关键
		 adjustMaxHeap(a, len, targetIndex);
	 }


}
void initHeap(int a[], int len) 
{
	for(int i=(len-1)/2;i>=0;i--)
	{
		adjustMaxHeap(a,len,i);
	}
}
int main()
{
	int a[8]={1,8,31,4,16,5,2,0};
	int len=8;
	initHeap(a, len);
	
	for(int i=len-1;i>0;i--)
	{
		int tmp;
		if(a[i]<a[0])
		{
		tmp=a[0];
		a[0]=a[i];
		a[i]=tmp;
		}
		//关键语句
		adjustMaxHeap(a, i,0);
	}
	for(int j=0;j<len;j++)
	{
		printf("\t%d",a[j]);
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值