堆排序

快速排序和归并排序都采用了分而治之、递归的思想。一直没仔细研究下堆排序,每次都忘,感觉好像蛮复杂的,在网上搜了下别人的文章,感觉写得好难的样子,顿时没读下去的动力了。个人喜欢简短准确的,于是翻开当年的《数据结构》,才三页,还不少图,正和我意,于是实现之。

堆排序的思想是不断地取堆顶元素,取完就结束。但要解决两个问题,一是建堆,二是调整堆。建堆其实也是通过由下往上调整堆实现的。简单吧?

简单的讲就是,把一维数组看成完全二叉树,构建成堆,于是二叉树中所有非叶子结点的值都不大于(或不小于)其左右孩子结点的值。这样堆顶肯定是数组中的最大值或最小值了,即对应所谓的大顶堆和小顶堆。

实现细节见代码,有细致的注释,不过比较拗口、啰嗦,不知道别人读不读得懂。。

#include<iostream>
using namespace std;

//交换a、b
void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void HeapAdjust(int *arr, int low, int high)//堆调整 使其成为大顶堆
{
	int temp = arr[low];//要调整的堆顶元素
	for(int j = 2*low+1; j <= high; j=j*2+1) //找到堆顶的左结点
	{
		if(j < high && arr[j] < arr[j+1])//存在右节点&&右节点大
			j++;
		if(temp > arr[j]) //原先的堆顶元素最大
			break;//直接跳出循环 否则往下 后面写else也没问题
		arr[low] = arr[j];//将大的元素给原先堆顶元素现在的位置(可能是一开始的堆顶也可能是中间层的堆顶)
		low = j;//保存大的元素位置
	}
	arr[low] = temp;//循环结束后用原先的堆顶元素填补大的元素位置
}

void HeapSort(int *arr, int length)
{
	for(int i=length/2-1; i >= 0; --i)
		HeapAdjust(arr , i, length-1);  //从完全二叉树的最后一个非叶子节点开始往上逐渐调整堆,即建堆的过程
	for(i=length-1; i > 0; --i)
	{
		swap(arr[0], arr[i]);//交换堆顶元素(大的数)和arr[0..i]中最后一个元素 这样排序出来是非递减的(数组中没有相同元素的话就是从小到大排序)
		HeapAdjust(arr, 0, i-1); //调整剩下的堆
	}
}

void Print(int *arr, int length)//打印
{
	for(int i = 0; i < length; i++)
	{
		printf("%6d",arr[i]);
		if(0 == (i+1)%10)
			cout<<endl;
	}
	cout<<endl;
}
void main()
{
	int arr[8] = {49,38,65,97,76,13,27,49};
	int length = 8;
	HeapSort(arr, length);
	Print(arr,length);
}




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值