标签:
堆排序算法时间复杂度为 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; }
标签:
原文地址:http://blog.csdn.net/jaster_wisdom/article/details/51335244