您的位置:首页 > 其它

排序算法(Max_Heap_Sort最大堆排序)

2015-05-16 10:04 302 查看
Max_Heap_Sort排序的基本原理及步骤

基本原理:利用最大堆堆顶记录的是最大的关键字这一特性。

详细步骤如下:

1. 先将待排数据建立成为一个最大堆(最大堆就是根结点的数值不小于左右孩子结点的数值);如文中Build_Max_Heap()函数

2. 然后再将根结点与最后一个叶子结点交换,取出最后一个叶子结点便得到待排数据中最大的结点;如文中Swap()函数

3. 交换之后的堆根结点很有可能不满足堆的性质(也即新的根结点数值很有可能大于左右孩子结点数值),因此对根结点进行一次Max_Heapify(),该函数的作用是通过下溯法通过比较和交换使得新堆的根结点也满足最大堆的性质;

4. 依次这样,直到取出最后一个结点。。。

Max_Heap_Sort排序是原址不稳定排序,它其实是改进的树形选择排序——>通过下溯法使得最大关键字置于堆顶,然后再与最后叶子结点进行交换。

*Max_Heap_Sort排序的时间复杂度是O(NlgN),空间复杂度为O(1)。

测试用例: 运行环境为VS2010

下面以待排数据长度N=20,数据数值范围Range=100和N=10000,Range=1000进行分析说明。

当N=20,Range=100时,运行结果如下:


当N=10000,Range=1000时,由于数据太长,这里只给出排序所需花费的时间为 Sorting spends about 13ms.

//Codes of the Max_Heap_Sort

void Heap_Sort(int *arr)
{
if(arr==NULL)
return;
Build_Max_Heap(arr);
for(int ii=N-1;ii>=1;--ii){
Swap(arr[0],arr[ii]);
N-=1;
Max_Heapify(arr,0);
}
}

void Build_Max_Heap(int *arr)
{//建立最大堆
if(arr==NULL)
return;
int lenflag=(N>>1)-1;
for(int ii=lenflag;ii>=0;--ii)
Max_Heapify(arr,ii);
}

void Max_Heapify(int *arr,int pflag)
{//最大堆的递归调整,暂且称它为最大堆重构
int lchildflag=2*pflag+1;//注意,这里存在数组中的数据下标
int rchildflag=2*pflag+2;   //是从0开始的.
int largestflag;//
if(lchildflag<N && arr[lchildflag]>arr[pflag])
largestflag=lchildflag;
else
largestflag=pflag;
if(rchildflag<N && arr[rchildflag]>arr[largestflag])
largestflag=rchildflag;
if(largestflag!=pflag){
Swap(arr[largestflag],arr[pflag]);
Max_Heapify(arr,largestflag);
}
}


//Codes of the main function and other auxiliary subfunctions

#include "stdafx.h"
#include <iostream>
#include <ctime>

using namespace std;

int N=10000;//待排序序列的个数
const int Range=1000;//待排序数字的范围

void InputNumber(int *,int );
void OutputNumber(int *,int);
void Heap_Sort(int *arr);
void Build_Max_Heap(int *arr);
void Swap(int &lhs,int &rhs);
void Max_Heapify(int *arr,int pflag);

int main()
{
int lenarray=N;
int arr[10000]={0};
InputNumber(arr,N);
cout<<"The input Numbers are-------------------"<<endl;
OutputNumber(arr,lenarray);
auto tstart=clock();
Heap_Sort(arr);
auto tend=clock();
auto totaltime=tend-tstart;
cout<<"The sorted Numbers are------------------"<<endl;
OutputNumber(arr,lenarray);
cout<<"Sorting spends about "<<totaltime<<"ms"<<endl;
return 0;
}

void InputNumber(int *arr,int N)
{
if(arr==NULL)
return;
for(int ii=0;ii<N;++ii)
arr[ii]=rand()%Range;
}
void OutputNumber(int *arr,int N)
{
for(int ii=0;ii<N;++ii)
cout<<arr[ii]<<'\t';
cout<<endl;
}

void Swap(int &lhs,int &rhs)
{
int temp;
temp=lhs;
lhs=rhs;
rhs=temp;
}


最大堆排序分析结束,代码纯属自己看相关理论算法后原创,转载请标明出处,欢迎与大家讨论研究,谢谢!下一篇将介绍桶序Bucket_Sort.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息