您的位置:首页 > 理论基础 > 数据结构算法

数据结构-堆排序

2016-12-09 15:44 197 查看

堆排序

堆排序

下面讨论利用堆进行排序的方法。可以分两种情况分别讨论:

① 如果初始序列是堆,则可通过反复执行如下操作而最终得到一个有序序列:

输出根:即将根(第一个元素)与当前子序列中的最后一个元素交换。

调整堆:将输出根之后的子序列调整为堆(元素个数比输出前少1个)。

向下筛。

② 如果初始序列不是堆,则首先要将其先建成堆,然后再按 ① 的方式来实现。

现在的问题是:如何由一个无序序列建成一个堆?

向上筛。

事实上,由无序序列建堆可通过反复调用筛选操作来实现。

为此,需满足筛选的条件,即左右子树必须为堆。

因此,建堆过程要从下往上逐棵子树地进行筛选。

从易于编程的角度出发,根的下标自然是按从大到小,即根的下标按照从n/2到1的次序将各子树调整为堆。

即:从最后一棵(最右边)高度为2的子树开始调整为堆。从右往左,自底向上(向总树根)逐层调整为堆。

【例】由初始序列(12,15,30,80,100,46,78,33,90,86,64,55,120,230,45)构建堆。

【解】首先由序列构建一棵完全二叉树,自最右高度为2的子树开始,然后从右往左,自底向上逐层调整为堆。

调整过程见后图。



代码块

#define maxlen 100
#define MaxSize 20

typedef int KeyType;    //定义关键字类型
typedef char InfoType[10];
typedef struct          //记录类型
{
KeyType key;        //关键字项
InfoType data;      //其他数据项,类型为InfoType
} RecType;              //排序的记录类型定义

class rank
{
public:
rank();
virtual ~rank();
RecType R[MaxSize];
//    int data[maxlen];
int high;
void shuru(int x);
void shuchu();
void sift(RecType R[],int low,int high);
void heapsort(RecType R[],int n);
void initlist();
};
#endif
#include "stdafx.h"
#include "rank.h"
#include "iostream.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

rank::rank()
{

}

rank::~rank()
{

}
void rank::initlist()//录入
{
//  printf("please input some 数:\n");

int i=1;
//    R[i]=0;
while(EOF!=scanf("%d",&R[i]))     //输入数
{
i++;
if(getchar()=='\n')
break;
}
high= i-1;
//    printf("data[top]= %d\n",data[top]);
}

void rank::shuchu()
{
for (int i=1; i<=high; i++)
printf("%d ",R[i]);
cout<<endl;
}

void rank::sift(RecType R[],int low,int high)
{
int i=low,j=2*i;                        //R[j]是R[i]的左孩子
RecType temp=R[i];
while (j<=high)
{
if (j<high && R[j].key<R[j+1].key)  //若右孩子较大,把j指向右孩子//j变为2i+1
j++;  //左孩子小于右孩子时,左右交换(左孩子要大于右孩子)
if (temp.key<R[j].key)//双亲结点小于左孩子时,交换(双亲结点要大于左孩子)
{
R[i]=R[j];                          //将R[j]调整到双亲结点位置上
i=j;                                //修改i和j值,以便继续向下筛选
j=2*i;
}
else break;                             //筛选结束
}
R[i]=temp;
}

void rank::heapsort(RecType R[],int n)
{
int i;
RecType temp;
for (i=n/2; i>=1; i--) //循环建立初始堆
sift(R,i,n);     //调整堆,形成75 57 48 40 19 34 38 11 6 13
4000
9 7
for (i=n; i>=2; i--) //进行n-1次循环,完成推排序
{
temp=R[1];       //将第一个元素同当前区间内R[1]对换
R[1]=R[i];
R[i]=temp;       //最大值交换到最后
sift(R,1,i-1);   //筛选R[1]结点,得到i-1个结点的堆 //前面的无序区调整为堆
}   //调整堆
}
#include "stdafx.h"
#include "rank.h"
#include "iostream.h"

int main(int argc, char* argv[])
{
rank r;
//  int x;
cout<<"请随意输入一些数字: ";
r.initlist();
cout<<"数组长度为: "<<r.high<<endl;
cout<<"未排序的结果为: ";
r.shuchu();
r.heapsort(r.R,r.high);
cout<<"堆排序之后的结果为: ";
r.shuchu();
//  printf("Hello World!\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  第一次发