/******************************************************************************************************************
文件说明:
【选择类排序】之【堆排序】
堆排序说明:
【1】在堆排序中,有三个关键的步骤,分别为:
【1】重建堆
【2】建初堆
【3】堆排序
【2】当堆顶元素发生改变时,如何重建堆?-----------【重建堆】
参考耿国华《数据结构》316页的图示,注意,重建堆的时候,分为两种具体的算法,重建大根堆和重建小根堆。
【3】如何由一个任意序列建初堆?-------------------【建初堆】
【4】如何利用堆完成排序?-------------------------【堆排序】
堆排序算法基本思想:
【1】将待排序记录按照堆的定义建初堆,并输出堆顶元素;
【2】将剩余的记录序列重建堆,在输出堆顶元素
【3】重复步骤2
*******************************************************************************************************************/
#include <iostream>
#include <algorithm>
using namespace std;
/*****************************************************************************************************************
模块说明:
重建堆-------调整堆
******************************************************************************************************************/
template<typename ElemType>void HeapAdjust(ElemType arrayT[],int iRootNum,int iLength)
{
int lChild = 2*iRootNum; //【1】iRootNum的左孩子节点序号
int rChild = 2*iRootNum+1; //【2】iRootNum的右孩子节点序号
int iMax = iRootNum; //【3】临时变量,存储大根堆的根节点序号(相对来说)
if(iRootNum<=iLength/2) //【4】如果iRootNum是叶节点就不用进行调整
{
if(lChild<=iLength&&arrayT[lChild]>arrayT[iMax])
{
iMax=lChild;
}
if(rChild<=iLength&&arrayT[rChild]>arrayT[iMax])
{
iMax=rChild;
}
if(iMax!=iRootNum)
{
std::swap(arrayT[iRootNum],arrayT[iMax]);
HeapAdjust<int>(arrayT,iMax,iLength); //【5】避免调整之后以max为父节点的子树不是堆
}
}
}
/*****************************************************************************************************************
模块说明:
建初堆
******************************************************************************************************************/
template<typename ElemType>void BuildHeap(ElemType arrayT[],int iLength) //【0】建初堆
{
for(int iNonLeafRootNum=iLength/2;iNonLeafRootNum>=1;iNonLeafRootNum--) //【1】非叶节点最大序号值为iLength/2
{
HeapAdjust<int>(arrayT,iNonLeafRootNum,iLength); //【2】调整堆
}
}
/*****************************************************************************************************************
模块说明:
堆排序
******************************************************************************************************************/
template<typename ElemType>void HeapSort(ElemType arrayT[],int iLength)
{
BuildHeap<int>(arrayT,iLength); //【1】建初堆
for(int i=iLength;i>=1;i--)
{
std::swap(arrayT[1],arrayT[i]); //【2】交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
HeapAdjust<int>(arrayT,1,i-1); //【3】重新调整堆顶节点成为大顶堆
}
}
/*****************************************************************************************************************
模块说明:
控制台应用程序的入口点
******************************************************************************************************************/
int main(int argc, char *argv[])
{
int arrayT[20]={0,10,9,8,7,1,2,3,4,5,6,100,90,80,70,60,50,40,30,20};//【1】数组的第一个元素不参与排序
int iLength = 19; //【2】实际参与排序元素的个数
HeapSort(arrayT,iLength);
for(int i=1;i<20;i++)
{
std::cout<<arrayT[i]<<std::endl;
}
std::system("pause");
return 0;
}
【Data_Structure笔记8】排序算法之【选择排序---堆排序】
最新推荐文章于 2023-04-02 17:12:32 发布