最大堆排序和最小堆排序的区别与实现(C++代码)

       堆排序可分为两部分,第一部分是建堆,第二部分是取出一个元素后调整堆。堆排序可以分成两种方式,构建最大堆(用于升序排列)和最小堆(用于降序排列),两者的差别只是修改代码中adjust函数中arr[index<arr[left]和arr[index]<arr[right]中的两个小于号改成大于号就可以。堆是用完全二叉树定义的,满足如下性质:有一个节点k,它的父节点是(k-1)/2,它的左子节点是2k+1,右子节点是2k+2。最大堆定义,每个节点都大于它的左右孩子。最小堆定义,每个节点都小于它的左右孩子。这个概念和搜索二叉树不一样。

       首先构建堆,不是说真的做个堆的结构出来,而是说对堆化这个数组,然后每次把堆头元素与堆尾交换,相当于把堆尾的元素拿出去了,再将前len-1个元素重新调整,最后输出的结果就是排序结果了。

       最大堆和最小堆用于升序或降序的区别,就在于每次被拿到数组尾巴的是大元素还是小元素。

//辅助交换函数
void Swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void adjust(int arr[], int root, int len)
{
	int left = 2 * root + 1;  // index的左子节点
	int right = 2 * root + 2; // index的右子节点
	int index = root;		  //左右中三者的最大值节点
	if (left < len && arr[index] < arr[left])
	{
		index = left;
	}
	if (right < len && arr[index] < arr[right])
	{
		index = right;
	}
	if (index != root)
	{
		Swap(arr[index], arr[root]);
		adjust(arr, index, len);
	}
}
// 堆排序
void heapsort(int arr[], int len)
{
	// 构建大根堆(从最后一个非叶子节点向上)
	for (int i = len / 2 - 1; i >= 0; i--)
	{
		adjust(arr, i, len);
	}
	// 调整大根堆
	for (int j = len - 1; j >= 1; j--)
	{
		Swap(arr[0], arr[j]); // 将当前最大的放置到数组末尾
		adjust(arr, 0, j);    // 将未完成排序的部分继续进行堆排序
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值