最近在研究排序算法,自己写了个函数模板。
最大堆排序根本的思路是将数组看作为二叉树,构建最大堆,最大数据在构建过程中移动到第一个位置,然后交换到最后一个位置,在调整最大堆,需要调整的数据不断递减,最后达到整个数组有序。
template<class T>
void HeapAdjust(T*pArr,int index, int nLength)
{
//假设整个数组是以第一个元素为根节点的二叉树,要构成最大堆,调整index位置元素的最终位置
if(!pArr)
return;
T temp =pArr[index];
//从左子节点开始查找,下标从0开始,左孩子一定是2*index+1,右孩子一定是2*index+2;
//步长i=2*i+1,从下一层继续
for (int i=2*index+1;i<nLength;i=2*i+1)
{//index节点是父节点,在父节点的子节点中比较找出较大的元素移到父节点,
//看看左右节点哪个大,用大的与父节点比较
if (i<nLength &&pArr[i] < pArr[i+1])
++i;
//父节点已经是最大的直接跳出循环,
//注意,循环是从最后一层节点级叶子节点开始的,
//所以父子节点值得大小判断只需要邻层比较,不用考虑跨层
if(!(temp<pArr[i]))
break;
//调整位置
pArr[index] = pArr[i];
//较小值位置
index =i;
}
//把原父节点的值转移到新的位置
pArr[index] = temp;
}
template<class T>
void HeapSort(T* pArr,int nLength)
{
if(!pArr)
return;
int i;
//初始化最大堆
for (i=nLength/2;i>=0;i--)
{
//调整节点从叶子节点的上一层开始,因为默认为是二叉树,所以选取节点从中间开始
//调整目的是每次调整本节点是所有子节点中最大的。
//当==0时,调整出最大元素在0位置。最大堆也构建完毕
HeapAdjust(pArr,i,nLength);
}
for (i= nLength-1;i>0;i--)
{
//将最大值往后放
T temp = pArr[0];
pArr[0]=pArr[i];
pArr[i]=temp;
//调整最大堆
//移除了最大元素,0位置的元素又需要调整了,0元素以下的子树已经是最大堆,
//只需要调整0位置,数组长度减一,因为最后一个已经是最大值了。
//每次调整都是针对0位置的操作,选出最大值往后放,最后全部有序。
HeapAdjust(pArr,0,i-1);
}
}