您的位置:首页 > 其它

欢迎使用CSDN-markdown编辑器

2016-04-14 19:48 344 查看
#堆排序算法(利用最大堆)

基础知识:

1.堆的定义(最大堆)

一个大小为n的堆是一颗包含n个结点的完全二叉树,该树中的每个结点的关键字值大于等于其双亲结点的关键字值。

当这颗完全二叉树以顺序对方式存储时,事实上排成了结点序列(k0,k1,k2,k3,…,kn-1)。所以堆又可以定义为:n个元素的序列(k0,k1,k2,k3,…kn-1),当且仅当k[i]>=k[2i+1] && k[i] >=k[2i+2]时称为最大堆。(最小堆类似)

2.堆排序思想:

1>将初始序列构成最大顶堆

2>将堆顶元素heap[0]与最后一个元素交换,此时得到新的序列(heap[0],heap[1],heap[2],..heap[n-2]),heap[n-1]。其中heap[n-1]为最大元素,将不参与新的建堆过程

3>由于交换元素后,原序列将不满足堆性质,对上步生成的n-1个元素重新进行建堆过程,即重复(1),(2).

3.建堆与排序图解



(http://img.blog.csdn.net/20160414201101071)

(http://img.blog.csdn.net/20160414201119486)

(http://img.blog.csdn.net/20160414201158837)

(http://img.blog.csdn.net/20160414201222144)

(http://img.blog.csdn.net/20160414201245119)

建堆图解

4.可执行代码

#include <stdio.h>
#include <iostream>
using namespace std;
void create_heap(int *heap,int n);
void adjust_down(int *heap,int r,int n);
int main()
{
int arr[] = {16,7,3,20,17,8,13};
int size = 7;
while(size>1){
create_heap(arr,size);
int temp = arr[size-1];
arr[size-1] = arr[0];
arr[0] = temp;
size--;
}

for(int i =0;i<7;i++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
void adjust_down(int *heap,int r,int n)
{
int child = 2*r + 1;
int temp = heap[r];
while (child <= n) {
if((child<n) && (heap[child+1] > heap[child])) child++;
if(temp>heap[child]) break;
heap[(child-1)/2] = heap[child];
child = 2 * child + 1;
}
heap[(child-1)/2] = temp;

}
void create_heap(int *heap,int n)
{
for(int i=(n-1)/2;i>-1;i--)
{
adjust_down(heap, i, n-1);
}
}


5.注意的问题

1>建堆过程中,heap[(child-1)/2] = heap[child],这一句我开始理解为heap[r]=heap[child],其实这样是不对的,因为建堆过程中,有向下调整的过程,临时值temp = heap[r]并不是简单的和第一代子结点交换就行,而是一直向下调整,直到合适的位置

2>create_heap函数中的n代表的是最大索引,而不是关键字个数

3>每次建堆都要用到下调堆结构函数,索引i的子代结点的索引为
2*i+1, 2*i+2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: