c语言 堆排序

大原则:

排升序用大堆

排降序用小堆

基本思想:将待排序的序列构造一个大堆。此时,整个序列的最大值就是堆根的根节点。将它移走(与堆数组的末元素交换,此时末元素就是最大值,即就是在数组的最后一个位置)。然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素的次大值。如此反复,便能得到一个有序序列了。

源码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>




void Swanp(int* x, int* y)
{
	int a = *x;
	*x = *y;
	*y = a;
}

void HeapAdjust(int* heap, int n, int x)
{
	int LeftSon = 2 * x + 1;
	int RightSon = 2 * x + 2;

	if (LeftSon <= n - 1)
	{
		int MaxSon = LeftSon;
		if (RightSon <= n - 1 && heap[LeftSon] < heap[RightSon])
			MaxSon = RightSon;

		if (heap[x] < heap[MaxSon])
		{
			Swanp(&heap[x], &heap[MaxSon]);

			HeapAdjust(heap, n, MaxSon);
		}
	}
}


//排升序 建大堆
void HeapCreate(int* heap, int n)
{
	//下滤法
	int deep=1;
	//确定深度  找最右边的一个叶子或 (满二叉树)的话找倒数第二层最右边的第一个
	while (1)
	{
		int min = pow(2, deep - 1) - 1;
		int max = pow(2, deep) - 1;
		if (min < n && max >= n)
			break;
		deep++;
	}
	int ace = pow(2, deep - 1) - 2;   //下滤的起始位置
	while (ace >= 0)
	{
		int LeftSon = 2 * ace + 1;
		int RightSon = 2 * ace + 2;
		if (LeftSon <= n - 1)
		{
			int MaxSon = LeftSon;
			if (RightSon <= n - 1 && heap[LeftSon] < heap[RightSon])
				MaxSon = RightSon;

			if (heap[ace] < heap[MaxSon])
			{
				Swanp(&heap[ace], &heap[MaxSon]);
				HeapAdjust(heap,n,MaxSon);
			}
		}
		ace--;
	}

}






void HeapSort(int* heap, int n)
{
	HeapCreate(heap, n);
	int i = n;
	while (i--)
	{
		Swanp(&heap[0], &heap[i]);
		HeapAdjust(heap,i, 0);
	}

}

解释一下:建堆过程中

ace找的就是倒数第二行的最右边的一个    采用下滤的方法  将最大值替换上来

本人画图水平有限 ,这个照片里面的图 很生动的描述了这一个过程。

这么下滤调整一遍  大堆就建好了。

堆建好了 下面就简单了    根节点替换最后一个    然后在进行调整

递归调整就好,就看有没有 左儿子  右儿子 进行比较一下    

递归结束条件就是,双亲节点不和儿子节点互换了。

测试一下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值