排序算法之堆排序(C/C++实现)

void swap(int& a, int& b) {
	int temp = a;
	a = b;
	b = temp;
}
//堆调整算法实现
void max_HeapAdjust(int* A, int index, int n) {
	if (2 * index < n){
		int cur = index;
		if (2 * index + 1 < n && A[2 * index + 1] > A[cur])
			cur = 2 * index + 1;
		if (2 * index + 2 < n && A[2 * index + 2] > A[cur])
			cur = 2 * index + 2;
		//(3)
		if (cur != index){
			swap(A[cur], A[index]);
			max_HeapAdjust(A, cur, n);
		}
	}
}
int* heapSort(int* A, int n) {
	//(1)
	for (int i = n / 2 - 1; i >= 0; i--)//该循环建堆(自下而上)
		max_HeapAdjust(A, i, n);
	//(2)
	for (int j = n - 1; j > 0; j--) {
		swap(A[j], A[0]);
		max_HeapAdjust(A, 0, j);//堆调整(自上而下)
	}
	return A;
}

在这里插入图片描述
算法思想:堆是一个完全二叉树,分有最大堆和最小堆。以最大堆(根的值大于左右子树的值,子树也是最大堆)为例。
就是堆顶和堆尾对换,并输出最后一个,剩下的进行堆调整再一次次循环下去
以数组A[6] = {1,5,3,2,2,4}为例,进行堆排序
算法解析:如图A所示,

  在第(1)中,循环执行max_HeapAdjust函数,函数
  index值分别为        2                  1                  0
  执行一次函数对比 A[5]  A[2]         A[3] A[1]           A[1]  A[0]
                  A[6]  A[2]         A[4] A[1]           A[2]  A[0]
  以当index=0为例,比较A[1]与A[0]   比较A[2]与A[0]
  因为A[0]<A[1],cur=1 故执行(3)
  在(3)中,A[0]与A[1]互换值,使得A[0]=5,A[1]=1,由于换了A[1],故需要比较A[1]与其两个子节点。cur=1传入max_HeapAdjust
  index=      1
  执行对比 A[3] A[1]  
          A[4] A[1]
  因为A[1]<A[3],cur=3 故执行(3)   重复以上步骤,直到建堆完成
  走完以上步骤,算是构建最大堆完成,即根节点A[0]最大,得到图C;向下继续走
  在(2)中,执行一次循环,互换根节点A[0] 与最后一个叶节点A[j],此时A[j]即A[5]为最大值,执行max_HeapAdjust
  此后每次循环index都是0,即每次都从堆根部与子节点对比,向下走构建最大堆(不包括刚才替换的A[5]),然后替换A[0]
  与刚刚A[j]即A[4]替换,此时A[4]为最大值,依次类推,最后得到数组A即按索引从小到大排序完成

总结
首先构建最大堆,自下而上构建(从叶节点到根节点)
其次,在最大堆上将根节点与最后一个叶节点互换值,然后排除此叶节点的其他节点,自上而下构建最大堆(从根节点到叶节点),
在最大堆上将根节点与最后一个叶节点互换值,然后排除此叶节点的其他节点,自上而下构建最大堆(从根节点到叶节点),
依次类推,所有的节点都被排除构建堆时,完成,由此得到的数组即根据索引由小变大排序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值