首先,什么叫堆呢?
堆 ( Heap )设有一个关键字集合,按完全二叉树的顺序存储方式存放在一个一维数组中。对它们从根开始,自顶向下,同一层自左向右从 1开始连续编号。若满足
Ki <= K2i && Ki <= K2i+1
或 Ki >= K2i && Ki >= K2i+1,
则称该关键字集合构成一个堆。
前者成为最小堆,后者称为最大堆。通俗来说,小顶堆就是堆顶元素是整个二叉树中最小的。同时每一个子树也都是一个小顶堆。
如何建立堆呢?
首先,对于一个存储在数组中的二叉树(完全二叉树)(下标从0开始),对于任意节点i 其左子下标为2*i+1,右子为2*i+2。将一无序序列看成一个完全二叉树,则最后一个非终端结点是第n/2(求地板)个元素,则从该元素开始自下向上逐步调整为小顶堆。
建堆算法如下(默认是):大顶堆
1. 首先找到最后一个非叶子节点。设最后一个节点的下标是i。那么最后一个非叶子节点的下标是k = (i-1)/2求地板。
2. 然后从下标K元素开始,看下标K元素的左右子是否比下标K大;如果没有访问K-1节点;如果有,选择左右子中最大的节点K1,交换K1和K。由于交换可能破坏了K1为根元素的最大堆,递归访问K1执行2操作直到最大堆建立完成
建堆算法描述
建堆:
int arr [1000];
int n;
void SortHeap(int rootindex,int lastindex)
{
//cout<<rootindex<<endl;
int biggerindex = rootindex;
int lChild = 2*rootindex + 1;
int rChild = 2*rootindex + 2;
if(rChild<=lastindex)
{
if(arr[lChild]>arr[rootindex]||arr[rChild]>arr[rootindex])
{
if(arr[lChild]>arr[rChild])
{
biggerindex = lChild;
}
else
{
biggerindex = rChild;
}
}
}
else if(lChild<=lastindex)
{
if(arr[lChild]>arr[rootindex])
{
biggerindex = lChild;
}
}
if(biggerindex!=rootindex)
{
int temps = arr[biggerindex];
arr[biggerindex] = arr[rootindex];
arr[rootindex] = temps;
//for(int i = 0 ; i < n; i++)
// {
// cout<<arr[i]<<" ";
// }
//cout<<endl;
SortHeap(biggerindex,lastindex);
}
}
void BuildHeap(int n)
{
//int lastp = (lastindex-1)/2;
int lastindex = n-1;
for(int i=(lastindex-1)/2;i>=0;i--)
{
SortHeap(i,lastindex);
}
}
堆排序
每次选取堆顶元素,将堆顶元素取出。然后将最后的元素放在堆顶,重新建成最大堆。重复n-1次void HeapSort()
{
int lastindex = n - 1;
while(lastindex>0)
{
int temps = arr[0];
arr[0] = arr[lastindex];
arr[lastindex] = temps;
lastindex--;
if(lastindex == 0 )
break;
SortHeap(0,lastindex);
}
}
全部代码
#include <iostream>
using namespace std;
int arr [1000];
int n;
void SortHeap(int rootindex,int lastindex)
{
//cout<<rootindex<<endl;
int biggerindex = rootindex;
int lChild = 2*rootindex + 1;
int rChild = 2*rootindex + 2;
if(rChild<=lastindex)
{
if(arr[lChild]>arr[rootindex]||arr[rChild]>arr[rootindex])
{
if(arr[lChild]>arr[rChild])
{
biggerindex = lChild;
}
else
{
biggerindex = rChild;
}
}
}
else if(lChild<=lastindex)
{
if(arr[lChild]>arr[rootindex])
{
biggerindex = lChild;
}
}
if(biggerindex!=rootindex)
{
int temps = arr[biggerindex];
arr[biggerindex] = arr[rootindex];
arr[rootindex] = temps;
//for(int i = 0 ; i < n; i++)
// {
// cout<<arr[i]<<" ";
// }
//cout<<endl;
SortHeap(biggerindex,lastindex);
}
}
void BuildHeap(int n)
{
//int lastp = (lastindex-1)/2;
int lastindex = n-1;
for(int i=(lastindex-1)/2;i>=0;i--)
{
SortHeap(i,lastindex);
}
}
void HeapSort()
{
int lastindex = n - 1;
while(lastindex>0)
{
int temps = arr[0];
arr[0] = arr[lastindex];
arr[lastindex] = temps;
lastindex--;
if(lastindex == 0 )
break;
SortHeap(0,lastindex);
}
}
int main()
{
cin >> n;
for(int i = 0 ; i < n; i++)
{
cin>>arr[i];
}
BuildHeap(n);
HeapSort();
for(int i = 0 ; i < n; i++)
{
cout<<arr[i]<<" ";
}
return 0;
}