這次跟大家一起分享一下堆排序:
(二叉)堆是一個數組,元素個數爲n,可以被看成一個近似的完全二叉樹。我們通過構造出最大堆(就是父節點大於或等於子節點的堆),得到數組中的最大元素(最大堆的根就是數組中最大的元素),然後將根和數組最後一個值交換位置,同時對數組的前n-1項繼續構造出最大堆;重複以上過程,我們最後就得到了一個從小到大排列的數組。
代碼在下邊,大家有什麼不理解的話可以留言討論。
#include<iostream>
#include<limits.h>
#include<math.h>
#define LEFT(i) 2*i+1; //左孩子
#define RIGHT(i) 2*i+2; //右孩子
#define PARENT(i) floor((i-1)/2); //parent
using namespace std;
void HEAPSORT(int *A,int size); //堆排序方法
void BUILD_MAX_HEAP(int *A,int size); //建最大堆
void exchange(int *A,int i,int j); //交換數組A的下標爲i和j的元素
void MAX_HEAPIFY(int *A,int i,int size); //使得以i爲根的二叉樹是最大堆
void Out(int *A); //打印輸出
int main()
{
int A[]={1,14,10,8,7,9,3,2,4,16};
HEAPSORT(A,10);
cout<<"結果:";
Out(A);
cout<<endl;
}
void Out(int *A){
for(int i=0;i<10;i++){
cout<<A[i]<<" ";
}
cout<<endl;
}
void HEAPSORT(int *A,int size){ //堆排序方法
cout<<"初始:";
Out(A);
cout<<endl;
BUILD_MAX_HEAP(A,size);
cout<<"最大堆:";
Out(A);
for(int i=size-1;i>=1;i--){
exchange(A,0,i);
size--;
MAX_HEAPIFY(A,0,size);
}
}
void BUILD_MAX_HEAP(int *A,int size)//建最大堆
{
int start=floor(size/2)-1;
for(int i=start;i>=0;i--)
{
MAX_HEAPIFY(A,i,size);
}
}
void MAX_HEAPIFY(int *A,int i,int size) //使得以i爲根的二叉樹是最大堆
{
int largest=0;
int l=LEFT(i);
int r=RIGHT(i);
if(l<=size-1 && A[l]>A[i]){
largest=l;
}
else
{
largest=i;
}
if(r<=size-1 && A[r]>A[largest]){
largest=r;
}
if(largest!=i){
exchange(A,i,largest);
MAX_HEAPIFY(A,largest,size);
}
}
void exchange(int *A,int i,int j){
int temp=0;
temp=A[i];
A[i]=A[j];
A[j]=temp;
}