堆排序

#include <stdio.h>

//首先对于堆的性质必须有了解,堆是用数组模拟的完全二叉树
//完全二叉树就是除了最底层以外所有的节点都是充满的,而且是从左向右充满
//没有以上两个条件堆排序就是不成立的
//通过以上二个条件可以得到以下性质
//如果数组的起点为0,那么对于任意的下标i,有i的左节点的下标为2i + 1,右节点下标为2i + 2
//
//

//提供交换用
void swap(int* x,int* y){
	int tem = *x;
	*x = *y;
	*y = tem;
}


//调整最大堆
//将以下标start作为根节点的子树调整为满足最大堆条件的子树,end是数组的最后一个下标
void max_heapify(int arr[],int start,int end){
	//左节点下标
	int left = 2 * start + 1;
	//右节点下标
	int right = 2 * start + 2;
	int largest = start;
	if(left <= end && arr[left] > arr[start])
		largest = left;
	if(right <= end && arr[right] > arr[largest])
		largest = right;

	//说明存在交换
	if(largest != start){
		swap(arr[&start],&arr[largest]);
		//交换之后,下面的子树由于交换了数据可能不再满足最大堆的性质,需要再次调整
		max_heapify(arr,largest,end);
	}
		
}


//建立最大堆
//思考如何才能建立最大堆
//把所有的非叶子节点的子树都调整一遍
void build_max_heapify(int arr[],int len){
	int i;
	for(i = len / 2 - 1 ; i>= 0 ; i--){//自底向上,一个一个的调整
		max_heapify(arr,i,len - 1);	
	}

}


void heap_sort(int arr[],int len){
	//将数组调整成最大堆
	build_max_heapify(arr,len);
	//然后将第一个位置的值和最后一个位置的值对调
	//第一个位置的值永远是最大的,对调之后最大的值就在数组的最后
	//如果我们此时将堆的长度减1,也就是将数组的长度-1,排除最大的那个元素
	//将数组前面的元素调整为最大堆,继续对调.....
	//要对调到什么时候呢?最后只剩两个元素的时候
	int i;
	for(i = len - 1;i >= 1;i--){
		swap(&arr[0],&arr[i]);
		max_heapify(arr,0,i - 1);
	}
	

}

















 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值