堆排序

堆排序

也是一种选择排序
堆:满足完全二叉树
-大顶堆:堆顶元素大于左右孩子的数据
-小顶堆:堆顶元素小于左右孩子的数据
例如:给出一组数据:12,3,21,32,1,34,12,35,34,18
在这里插入图片描述
堆排序是借助大顶堆和小顶堆来完成升序或降序的排序的。
思想:先把数据调整为大顶堆或小顶堆(升序调整为大顶堆,降序调整为小顶堆),接下来把堆顶元素与最后一个元素做交换,而此时堆中最后一个元素就是最大元素(大顶堆的堆顶放的是当前堆里最大的元素),然后从堆中剔除最后一个元素,再把整个堆调整为大顶堆,然后再把调整后的堆顶元素与最后一个元素做交换(当前堆顶的元素放到当前堆的末尾位置),之后又剔除最后一个元素,再堆整个堆做调整成为大顶堆,依次这样…直到剔除完最后一个元素。

注意:组织大顶堆时得从后往前组织

详细可参见下面得代码:

代码实现

#include<stdio.h>

void ShowArr(int arr[],int len)
{
	int i = 0;
	for( ; i < len; i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        

void HeapAdjust(int arr[],int i,int len)//标识父亲结点得位置
{
	int j = 2 * i + 1;//左孩子位置得标识
	int tmp;
	for( j; j < len; j = 2 * i + 1)
	{
		if((j < len - 1) && (arr[j+1] > arr[j]))//有左孩子也有右孩子得情况    右孩子大于左孩子
		{
			j++;
		}//j标识左右孩子中较大得数据
		if(arr[i] > arr[j])//父亲比左右孩子较大者大
			break;
		tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
		i = j;//父亲结点得位置    标识到左右孩子中发生调整得支路
	}
}

void HeapSort(int arr[],int len)
{
	int i = (len - 2) / 2;//起始标识最后一个父亲结点的位置
	int tmp;
	for( i; i >= 0; i--)
	{
		HeapAdjust(arr,i,len);
	}
	for(i = len - 1; i > 0; i--)//i = len - 1标识最后一个元素的下标n
	{
		tmp = arr[i];
		arr[i] = arr[0];
		arr[0] = tmp;
		HeapAdjust(arr,0,i);
	}
}

int main()
{
	int arr[] = {12,3,21,32,1,34,12,35,34,18};
	int len = sizeof(arr)/sizeof(arr[0]);
	ShowArr(arr,len);
	HeapSort(arr,len);
	ShowArr(arr,,len);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值