C++编程练习(13)----“排序算法 之 堆排序“

时间:2022-12-10 07:06:48

堆排序

堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆(也叫最大堆);或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(也叫最小堆)。

最小堆和最大堆如下图示:

C++编程练习(13)----“排序算法 之 堆排序“

可以发现:根结点一定是堆中所有结点最大(小)者。

堆排序的基本思想(以大顶堆为例):将待排序的序列构成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的 n-1 个序列重新构成一个堆,这样就会得到 n 个元素中的次大值。如此反复执行,便能得到一个有序序列了。

堆排序的思想用例图解释如下:

1. 初始最小堆的建立过程(自下向上逐步调整为最小堆)

C++编程练习(13)----“排序算法 之 堆排序“

C++编程练习(13)----“排序算法 之 堆排序“C++编程练习(13)----“排序算法 之 堆排序“C++编程练习(13)----“排序算法 之 堆排序“

具体代码如下:

1、排序前的一些准备工作,建立合适的排序需要的结构。

/********* 排序用到的结构  头文件sort_struct.h ************/
#define MAXSIZE 100 //要排序数组个数最大值 class SqList{
public:
int r[MAXSIZE+1];
int length;
}; /* 交换L中数组r下标为i和j的值 */
void swap(SqList *L, int i, int j)
{
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
} /* 显示数组内容 */
void showSqList(SqList *L)
{
for(int i=1;i<=L->length;i++)
std::cout<<L->r[i]<<" ";
std::cout<<std::endl;
}

2、编写主文件,实现排序与测试。

/********* C++堆排序算法 ************/
#include<iostream>
#include<time.h>
#include"sort_struct.h"
using namespace std; /* 本函数调整L->r[s]的关键字,使L->r[s...m]成为一个大顶堆 */
void HeapAdjust(SqList *L,int s,int m)
{
int temp,j;
temp = L->r[s];
for(j=2*s;j<=m;j*=2) //沿关键字较大的孩子结点向下筛选
{
if(j<m && L->r[j]<L->r[j+1])
++j; //j为关键字中较大的孩子结点的下标
if(temp>=L->r[j]) //如果关键字均大于孩子结点,跳出
break;
L->r[s] = L->r[j]; //否则交换关键字与较大孩子结点的内容
s = j;
}
L->r[s] = temp; //完成插入
} /* 对顺序表L进行堆排序 */
void HeapSort(SqList *L)
{
int i;
for (i=L->length/2;i>0;i--) //把L中的r构建成一个大顶堆
HeapAdjust(L,i,L->length); for (i=L->length;i>1;i--)
{
swap(L,1,i); //将堆顶记录和当前未经排序子序列的最后一个记录交换
HeapAdjust(L,1,i-1); //将L->r[1...i-1]重新调整为大顶堆
}
} int main()
{
int num[] = {0,50,30,25,15,84,56,34,99,54,111,24,43,6,62,124};
SqList *L = new SqList;
L->length = sizeof(num)/sizeof(int)-1;
for(int i=1;i<=L->length;i++)
L->r[i] = num[i];
cout<<"排序前:";
showSqList(L);
clock_t start = clock();
HeapSort(L);
clock_t end = clock();
double time = ((double)(start-end)) / (double)CLOCKS_PER_SEC * 1000;
cout<<"排序后:";
showSqList(L);
cout<<"耗时:"<<time<<"ms"<<endl;
return 0;
}

运行结果如下:

C++编程练习(13)----“排序算法 之 堆排序“

由于待排序样本太少,耗时显示为0。