还是,老规矩,对排序——是一种选择类型的排序,因为选择的方式不同,所以在堆排序中,堆顶要么最大,要么最小,每次这样拿,直到剩下最后一个位置。
堆排序,可没有前面几种那么简单,因为它设计到一个建堆问题,也就是如何创建堆的,要想看懂堆排序,首先,你必须看懂sift函数,好了,先看代码,再来分析。
#include<iostream>
using namespace std;
template <class T>
void hap(T p[],int n){
int i,mm;
T t;
mm=n/2;
for(i=mm-1;i>=0;i--)
sift(p,i,n-1);
for(i=n-1;i>=1;i--)
{
t=p[0];p[0]=p[i];p[i]=t;
sift(p,0,i-1);
}
return;
}
template <class T>
static sift(T p[],int i,int n){
int j;
T t;
t=p[i];j=2*(i+1)-1;
while(j<=n){
if((j<n)&&(p[j]<p[j+1])) j=j+1;
if(t<p[j]){
p[i]=p[j];i=j;j=2*(i+1)-1;
}
else j=n+1;
}
p[i]=t;
return 0;
}
1.你要明白,它是用一维数组存储的,什么意思?下标从0开始。
2.父亲的下标和儿子的有什么关系?画个图,自己看
3.建堆是从哪个点开始的?第一个非叶子节点?在哪里n/2的位置
4.把堆顶元素取出,与最后元素交换,此时堆顶不符合,那么调整堆
5,sift函数,p数组指针不解释,i表示当前的这个节点,n表示要调整的下标,下标,下标,亲,你明白我说什么吗?
好了,你既然弄懂了这些,那你就能看懂了。