您的位置:首页 > 其它

堆排序

2016-05-06 22:55 218 查看
堆排序算法时间复杂度为 O(nlgn)

堆从结构上讲,应该是一棵完全二叉树。在堆排序中一个很重要的概念是,维持最大堆的特性。最大堆就是每个节点的值比它左右孩子节点都要大。

我们首先将非叶子节点 都维持最大堆的特性一次。就是说保证非叶子节点它的左右孩子都比它的值要小。build_max_heap函数实现

其中,一个很重要的函数是max_heapify,它的功能是控制单个节点,保证它的孩子节点小于它的值。如果碰到比它大的情况,就进行交换。这里要注意的是,交换之后要进行递归调用max_heapify,保证它的子节点满足最大堆的性质。

最后,在主函数里,初始化堆,将数组第一个元素,也就是最大的元素(堆的根节点最大),与最后一个元素交换,然后从新的根节点开始max_heapify,然后将第一个元素调到后面去,这样循环length-1次,就会从小到大排好序。

稳定性分析:堆排序是不稳定的排序算法

#include <iostream>
using namespace std;

void max_heapify(int A[],int i,int heap_size){
int left = i*2;
int right = i*2 + 1;
int largest;
if(left<=heap_size && A[left] > A[i])
largest = left;
else
largest = i;
if(right <= heap_size && A[right] > A[i])
largest = right;
if(largest != i){   //exchange A[i] 和 A[largest]
int temp = A[i];
A[i] = A[largest];
A[largest] = temp;
max_heapify(A,largest,heap_size);  //递归循环
}
}

void build_max_heap(int A[],int length,int heap_size){
for(int i = length/2; i>=1; i--){
max_heapify(A,i,heap_size);    //维持最大堆的特性
}
}

int main(){
int input[] = {5,1,6,3,2,7,3};
int length = sizeof(input)/sizeof(int);
int A[length+1];    //将input数组转化为A数组,下标以1开始
for(int j=1;j<length+1;j++){
A[j] = input[j-1];
}
int heap_size = length;
build_max_heap(A,length,heap_size);     //建堆
for(int i = length;i>=2;i--){
int temp = A[1];    //此时A[1]一定是最大的
A[1] = A[i];
A[i] = temp;
heap_size --;
max_heapify(A, 1, heap_size);
}
for(int i=1;i<length+1;i++){
cout<<A[i]<<" ";
}
return 0;
}

堆排序的图形化表示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: