您的位置:首页 > 编程语言 > C语言/C++

创建堆,堆排序的详细实现过程,C++完整代码

2015-08-15 13:59 507 查看
堆的基本概念不在此介绍,各位看官自行百度。由于堆的特性导致堆可以用数组进行模拟,所以堆排序其实是在数组(即堆)上进行排序的过程,在所有堆的操作中,都离不开一个操作:调整堆,该过程使堆保持堆的性质(大堆或小堆的性质)。在介绍堆排序之前必要要介绍如何创建堆,由于堆是使用数组保存的,所有我的理解是,建堆的过程就是堆化数组,即使给定的数组具有堆的性质。堆化的过程其实就是调整堆的过程,我们把调整堆的过程定义成一个单独的函数void AdjustHeap(int heap[], int root_index, int
heap_length),参数分别是代表堆的数组,要调整的堆的根节点在数组中的下标,注意是下标,建议读者自己画个图模拟调整堆的过程。第三个参数是堆的长度,在这里就让他等于数组的长度,其实可以不相等。

调整堆的过程如下:

1.根据根节点下标,确定左右子节点的下标。

2.找出根节点和左右子节点中最小值的下标,注意该过程要判断边界,即左右子节点的下标是否超出堆的长度。

3.如果最小值的下标等于根节点的下标,函数返回。

4.否则,交换把根节点与最小值交换,由于交换可能破坏了最小值所在子树的对性质,所以递归调用AdjustHeap函数。

那么现在还有一个问题,就是堆化的时候,从哪个节点开始调整堆呢?这个也是建堆的关键,我们可以这样想,子节点已经是堆了,无需在调整了,所以我们没必要从最后一个节点开始调整,一般是从(heap_length/2)开始调节,一直到下标1为止(堆的下标一般从1开始,0位置不用),从(heap_length/2)开始调节的原因是完全二叉树的性质决定的。这样遍历一遍,对每个节点调用堆调整函数就完成建堆了。

堆排序的思想比较简单,取出堆的第一个元素,调整堆,循环下去,知道取完为止。实现的过程就是先把堆顶元素和堆的最后一个元素互换,堆长度减1,再调整堆,知道堆的长度为1。这样就使堆排序的空间复杂度为O(1)了,注意的是大顶堆排完序之后数组中元素的顺序是从小到大,小顶堆是从大到小。

完整代码如下:

#include <iostream>
#define Max 11
int heap[Max];

void AdjustHeap(int heap[], int root_index, int heap_length) //调整堆,这里是最小堆
{
int left_child_index = root_index * 2;
int right_child_index = left_child_index + 1;
int min_index = root_index;

if (left_child_index < heap_length && right_child_index < heap_length)
{
if (heap[left_child_index] < heap[root_index])
{
if (heap[left_child_index] < heap[right_child_index])
min_index = left_child_index;
else
min_index = right_child_index;
}
else
{
if (heap[right_child_index] < heap[root_index])
min_index = right_child_index;
else
min_index = root_index;
}
}

if (left_child_index < heap_length && right_child_index >= heap_length) //这种情况是左子节点是最后一个元素的情况
{
if (heap[left_child_index] < heap[root_index])
min_index = left_child_index;
else
min_index = root_index;
}

if (min_index != root_index)
{
int t = heap[root_index];
heap[root_index] = heap[min_index];
heap[min_index] = t;

AdjustHeap(heap,min_index,heap_length);
}

return;
}

void CreateHeap(int heap[], int heap_length) //建堆
{
for (int i = (heap_length / 2); i >= 1; --i)
AdjustHeap(heap, i, heap_length);
}

int main()
{
heap[0] = -1;
for (int i = 1; i != Max; ++i)//输入数组
std::cin >> heap[i];

CreateHeap(heap, Max); //建堆,即堆化
for (int i = 0; i != Max; ++i)
std::cout << heap[i] << " ";
std::cout << std::endl;
//堆建好的堆进行排序
int t = Max;
while (t != 1)
{
int tmp = heap[t - 1];
heap[t - 1] = heap[1];
heap[1] = tmp;
AdjustHeap(heap, 1, t-1);
--t;
}

for (int i = Max - 1; i != 0; --i)
std::cout << heap[i] << " ";
std::cout << std::endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: