老生常谈,开篇介绍,定义先行
堆排序:
堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质(即子结点的键值或索引总是小于(或者大于)它的父节点)。
实现
-
最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
-
创建最大堆(Build Max Heap):将堆中的所有数据重新排序
-
堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 (来自百度)
代码1.0(错误版本)
#include <iostream>
using namespace std;
//交换
void swap(int*a,int*b){
int t=*a;
*a=*b;
*b=t;
}
//最大堆调整(Max Heapify)
void MaxHeapify(int a[],int start,int end){
int f=start;
int lchild=2*f+1;
int rchild=2*f+2;
int son=lchild;
while(lchild<=end){
if((a[lchild]<a[rchild])&&(rchild<=end)){//1
son=rchild;
}
if(a[f]>a[son]){
return;
}
else {
swap(a[f],a[son]); //2
f=son; //2
son=2*f+1; //2
}
}
}
void heapsort(int a[],int len){
//得到最大二叉堆(从最后一个父亲开始建),a[0]是最大的
for(int i=len/2-1;i>=0;i--)
MaxHeapify(a, i, len - 1);
//整体排序·
for(int j=len-1;j>0;j--){
//交换a[0]a[j]后,a[j]是最大的
swap(a[0],a[j]);
//保证堆的稳定大小,使得在0----j-1中a[j]依然最大
MaxHeapify(a,0,j-1);
}
}
int main(){
int a[12]={3,4,5,6,7,1,2,3,8,9,10,0};
int len=sizeof(a)/sizeof(a[0]);
cout<<"before:"<<endl;
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
heapsort(a,len);
cout<<"after:"<<endl;
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
输出结果:
你没看错,就是没有输出。
错误原因:
没有输出,意味着程序在某一步骤死掉了,跳不出来,多为循环,这是就要写输出了来判断问题出现的位置
1.if((a[lchild]<a[rchild])&&(rchild<=end))值得注意的是&&会涉及短路规则,在逻辑上,要先判断它是否有右儿子,再比较出最大的儿子。出于规范,我将这两句话调换位置
2.可以看到,交换之后,对father变量进行了刷新,对最大儿子变量son也进行了刷新,但是,注意,我们的判断条件是rchild和lchild,这两个数据并未刷新,循环死掉;
代码2.0
#include <iostream>
using namespace std;
//交换
void swap(int*a,int*b){
int t=*a;
*a=*b;
*b=t;
}
//最大堆调整(Max Heapify)
void MaxHeapify(int a[],int start,int end){
int f=start;
// int lchild=2*f+1;
// int rchild=2*f+2;
int son=2*f+1;
while(son<=end){
if((son+1<=end)&&(a[son]<a[son+1])){
son++;
}
if(a[f]>a[son]){
return;
}
else {
swap(a[f],a[son]);
f=son;
son=2*f+1;
}
}
}
void heapsort(int a[],int len){
//得到最大二叉堆(从最后一个父亲开始建),a[0]是最大的
for(int i=len/2-1;i>=0;i--)
MaxHeapify(a, i, len - 1);
//整体排序·
for(int j=len-1;j>0;j--){
//交换a[0]a[j]后,a[j]是最大的,a[0]是在0---j最小的
swap(a[0],a[j]);
//保证堆的稳定大小,使得在0----j-1中a[0]最大
MaxHeapify(a,0,j-1);
}
}
int main(){
int a[12]={3,4,5,6,7,1,2,3,8,9,10,0};
int len=sizeof(a)/sizeof(a[0]);
//int len=12;
cout<<"before:"<<endl;
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
heapsort(a,len);
cout<<"after:"<<endl;
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
结尾·放个彩蛋哦
推荐一个可视化的数据结构与算法是网站(emm动图演示排序,链表会更容易些吧,还提供代码运行处)