排序算法之堆排序

本文以最大堆为例。

首先是一个交换对象值的函数

void swap(int& a, int& b)

{
int tmp = a;
a = b;
b = tmp;
}

// 对的下移操作:加入一个元素破坏了最大堆的性质:它太小了,于是我们需要把它向下移动到合适的位置

void shift_down(int H[], int n, int i)
{

while (i * 2 <= n)

{
i = i * 2;
if (i + 1 <= n && H[i + 1] > H[i])
{
i = i + 1;
}

if (H[i / 2] < H[i])
{
swap(H[i / 2], H[i]);
}
else
{
break;
}
}
}

// 堆的建立:把叶子节点以上的所有节点(即前一半节点,都下移到合适的位置)

void make_heap(int H[], int n)
{
H[0] = H[n];

int i;
for (i = n / 2; i >= 1; i--)
{
shift_down(H, n, i);
}

}

// 堆排序:把原来的数组(n个元素)建立成最大堆后,那么第一个元素肯定是最大元素,那么把第一个元素和最后一个元素互换,最大元素就是最后一个元素了,把堆的大小减一(只考虑前n-1个元素),把换上去的比较小的元素下移到合适的位置,那么前n-1个元素又组成了一个最大堆,重复以上的过程即可

void heap_sort(int H[], int n)
{

int i;
make_heap(H, n);

for (i = n; i > 1; i--)
{
swap(H[1], H[i]);
shift_down(H, i - 1, 1);
}
}

以上的每个函数除了make_heap外,都可以写成递归的形式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值