数据结构与算法之堆排序

堆排序算法思想

堆是一颗二叉树,这样的二叉树是局部有序的,任何节点与其兄弟节点之间都没有必然的顺序联系,但是它与父子节点之间有大小顺序关系,按照关系的不同,分为最大值堆和最小值堆
最大值堆:子节点比父节点小的堆,根节点是树中最大的节点。
最小值堆:子节点比父节点大的堆,根节点是树中最小的节点。

堆排序的两种调整方法:向下调整、向上调整,实现堆排序就要理解物理到逻辑映射关系

  • 将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
  • 将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
  • 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

下面实现主要是关于堆排序的降序实现:

堆排序的具体实现

//堆排序  最小堆,根节点小于左右孩子节点
void PrintInt(int* ar, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%5d", ar[i]);
	}
	printf("\n");
}
void FilerDown(int* nums, int strat, int end) //向下调整
{
	int i = strat ;
	int j = i * 2 + 1;
	int temp = nums[i];
	while (j<=end)
	{
		if (j<end&&nums[j] > nums[j + 1])j += 1;  //找左孩子和右孩子谁最小,将最小值赋值给j
		if (temp <= nums[j])break;  
		nums[i] = nums[j];
		i = j;
		j = i * 2 + 1;
	}
	nums[i] = temp;
}

void HeapSort(int* nums, int n)
{
	if (nullptr == nums || n < 2)return;
	int pos = (n - 2) / 2;   
	while (pos >= 0)  
	{
		FilerDown(nums, 0, n - 1);  //调整,从最下面进行调整
		--pos;
	}
	pos = n - 1;
	while (pos > 0)
	{
		std::swap(nums[0], nums[pos]); //交换,将最小的值放入数组后面
		--pos;
		FilerDown(nums, 0, pos);
	}
}

void FilerUp(int* nums, int start)  //向上调整
{
	int j = start, i = (j - 1) / 2; 
	int temp = nums[j];
	while (j > 0)
	{
		if (nums[i] <= temp)break;
		nums[j] = nums[i];
		j = i;
		i = (j - 1)/2;
	}
	nums[j] = temp;
}

int main()
{
	int ar[] = { 53,17,78,9,45,65,87,23 };
	int n = sizeof(ar) / sizeof(ar[0]);
	PrintInt(ar, n);
	HeapSort(ar, n);
	PrintInt(ar, n);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡蓝色的经典

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值