swust oj 1015: 堆排序算法

堆的概念

堆(Heap)是计算机科学中一类特殊的数据结。堆通常是一个可以被看作一棵完全二叉树的数组对象。可以理解为堆就是一颗用数组是实现的完全二叉树。

性质

  • 堆中某个结点的值总是不大于或不小于其父结点的值;

  • 堆总是一棵完全二叉树

将根结点最大的堆叫做最大堆或大根堆,根结点最小的堆叫做最小堆或小根堆。

下标的关系

  • 父亲的下标为i
  • 左孩子的下标为2*i+1
  • 右孩子的下标为2*i+2

 堆的实现

堆向下调整算法

前提:左右子树都是一个堆,才能进行调整

算法思想 

找出左右孩子中最小的一个,与父亲进行比较

若小于父亲,二者交换位置,更新父亲结点,孩子结点

一直重复上述过程

若不小于父亲说明建堆完成

代码实现 

void Adjustdown(datatype* arr, int n, int root)//向下调整
{
	//前提:左右子树已经是小堆
	//找出左右孩子中小的那个
	int parent = root;
	int child = root * 2 + 1;//假设小的那个是左孩子
	while (child < n)
	{
		if (child+1<n&&a[child + 1] < a[child])++child;//找出小的那个孩子 
		//child+1判断特殊情况
		//即child为左孩子且为叶子节点且不存在右孩子 
	

		//如果父亲大于孩子则交换
		if (arr[child] < arr[parent])
		{
			swap(arr[child], arr[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

建堆过程

仅需从倒数第一个非叶子结点开始开始调整

代码实现

	for (int i = (n - 1-1)/2; i >= 0; i--)
	{
		adjust_down(arr, i, n);
	}

题目描述

其实就是一个建堆的过程,故题解代码如下

题目代码

#include <iostream>
using namespace std;
int arr[1000];

void adjust_down(int* arr, int root,int n)
{
	int parent = root;
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && arr[child + 1] < arr[child])child++;
		if (arr[child] < arr[parent])
		{
			swap(arr[child], arr[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}


int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)cin >> arr[i];
	for (int i = (n - 1-1)/2; i >= 0; i--)
	{
		adjust_down(arr, i, n);
	}
	for (int i = 0; i < n; i++)cout << arr[i] << ' ';
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值