点击查看代码
#include <iostream>
using namespace std;
/*小顶堆函数降序排序修改:
1、MaxHeap函数中改为if (c < end && a[c] > a[c + 1])//如果有右孩子,则用较小者与父结点进行比较
2、MaxHeap函数中改为if (tmp > a[c])//如果父结点大于孩子结点,则互换两结点的值
*/
//构造大顶堆,顶点下标范围[start,end]
/*
函数功能:构造大顶堆
参数列表:
a:指向待排序序列的指针
start:第一个非叶子结点
end:待排序序列最后一个元素
*/
void MaxHeap(int* a, int start, int end) {
int f = start;//f是父结点位置
int tmp = a[f];//先暂存要比较的父结点大小
int c = 2 * f + 1;//左孩位置
//构造大顶堆,左孩没有超出树的范围表明该分支还有下一层孩子结点需要判断
while (c <= end) {
if (c < end && a[c] < a[c + 1]) c++; //如果有右孩,则用较大的孩子与父结点进行比较
//如果父结点小于孩子结点,则互换两结点的值
if (tmp < a[c]) {
a[f] = a[c];
a[c] = tmp;
f = c;//以原孩子结点编号作为新的父结点编号,检查该分支是否还有下一层孩子结点需判断
c = 2 * f + 1;//求新的左孩结点编号
}
else break; //如果父结点不小于孩子结点,此时已是大顶堆,不需要再向下判断,可提前结束while循环
}
return;
}
//堆排序(升序排序)
void HeapSortUp(int a[], int n) {
int i, tmp;
//初始化大顶堆不需要考虑元素是否已被取出排序
for (i = n / 2 - 1; i >= 0; i--) {
MaxHeap(a, i, n - 1);
}
//将根结点a[0](最大值)放到序列最后(升序排序)
for (i = n - 1; i > 0; i--)
{
tmp = a[0];//将根结点a[0]与最后一个结点a[i]互换
a[0] = a[i];
a[i] = tmp;
//重新构造大顶堆需要考虑元素是否已被取出排序
//start为序列第一个未排序元素a[0],end为最后一个未排序元素a[i-1]
MaxHeap(a, 0, i - 1);
}
return;
}
int main(){
int i;
int a[] = { 20,30,90,40,70,60,110,10,100,50,80 };
int n = (sizeof(a)) / (sizeof(a[0]));
cout << "序列个数:" << n << endl;
cout << "排序前:";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
HeapSortUp(a, n);
cout << "排序后:";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}