主要思想:
1、基本概念:
堆:一种数组对象,可以视作一棵完全二叉树。二叉堆有两种:最大堆和最小堆。最大堆中的最大元素放在根结点中,并且在以某一个结点为根的子树中,各结点的值都不大于该子树根结点的值。最小堆的组织方式则刚好相反。
堆排序:首先按照最大堆(最小堆)构造堆,再将堆顶元素与堆尾元素交换,取出堆尾元素(即目前堆中的最大值),并在堆中将堆尾元素删除,再将目前的堆重新组织成最大堆(最小堆)。循环上面的过程,直到堆的元素全部取出。
2、算法复杂度:
最坏情况:O(nlgn)
平均情况:O(nlgn)
3、实现代码:
#include <iostream>
using namespace std;
//最大堆的实现
//最大化堆
//A是待排序数组,i是子树的根位置,heap_size是堆的大小
void maxHeapify(int A[],int i,int heap_size)
{
int left = 2*i;
int right = 2*i+1;
int largest = 0;
//在根和左右节点中找出最值
if(left<=heap_size && A[left-1]>A[i-1])//i是从1开始的,数组下标从0开始
largest = left;
else
largest = i;
if(right<=heap_size && A[right-1]>A[largest-1])
largest = right;
//根不是最大值时进行交换
if(largest!=i)
{
int temp = A[largest-1];
A[largest-1] = A[i-1];
A[i-1] = temp;
//递归保持最大堆性质
maxHeapify(A,largest,heap_size);
}
}
//建立最大堆
void buildMaxHeap(int A[],int size_A)
{
int heap_size = size_A;
for(int i=floor(size_A/2.0);i>=1;i--)
{
maxHeapify(A,i,heap_size);
}
}
//堆排序
void heapSort(int A[],int size_A)
{
//建立最大堆
buildMaxHeap(A,size_A);
//初始化堆的大小
int heap_size = size_A;
//取出堆顶元素(即最大值),重新构建最大堆
for(int i=size_A;i>=2;i--)
{
int temp = A[0];
A[0] = A[i-1];
A[i-1] = temp;
heap_size--;
maxHeapify(A,1,heap_size);
}
}
int main(int argc,char* argv[])
{
int A[] = {4,1,3,2,16,9,10,14,8,7,45,11,89};
int length = sizeof(A)/4;
cout<<"排序前:";
for(int i=0;i<length;++i)
{
cout<<A[i]<<" ";
}
cout<<endl;
heapSort(A,length);
cout<<"排序后:";
for(int i=0;i<length;++i)
{
cout<<A[i]<<" ";
}
cout<<endl;
return 0;
}