TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
堆排序算法是建立在二叉树的堆结构上的,通过交换堆(一维数组)中的元素,并进行上浮或下沉函数运算实现多次调整
堆排序算法的复杂度低,和快速排序属于相同速度级别的一种快速的排序算法
下面以最小堆和最大堆来进行堆排序算法的实现,具体内容在代码中进行讲解
1.最小堆 堆排序
#include"iostream"
#include"cstdio"
using namespace std;
int h[100]; //堆
int n;
int num; //num的意义在于,在n的值不断减小的时候,保存n原来的值,以便我们在最后输出排序后的数组的时候,丢失原来的数组元素个数的值
void swap(int x,int y) //必要的交换函数
{
int t;
t=h[x];
h[x]=h[y];
h[y]=t;
}
void siftdown(int i) //子树的向下调整,构建局部最小堆
{
int t,flag=0;
while(i*2<=n&&flag==0)
{
if(h>h[i*2])
{
t=2*i;
}
else
{
t=i;
}
if(i*2+1<=n)
{
if(h[t]>h[2*i+1])
{
t=2*i+1;
}
}
if(t!=i)
{
swap(t,i);
i=t;
}
else
{
flag=1;
}
}
}
/*void siftup(int i)
{
int flag=0;
if(i==1)
{
return ;
}
else
{
while(i!=1&&flag==0)
{
if(h<h[i/2])
{
swap(i,i/2);
i=i/2;
}
else
{
flag=1;
}
}
}
}*/
int delet() //每次返回对顶元素,堆顶元素出堆的顺序是排序好的
{
int t;
t=h[1];
h[1]=h[n]; //交换的目的是和下面的n--和siftdown共同保证每次出堆的是标准的要求的顺序
n--;
siftdown(1);
return t;
}
int main()
{
cin>>n;
num=n;
for(int i=1;i<=n;i++)
{
scanf("%d",&h);
}
for(int i=n/2;i>=1;i--)
{
siftdown(i);
}
for(int i=1;i<=num;i++)
{
printf("%d ",delet());
}
return 0;
}
2.最大堆 堆排序
#include"iostream"
#include"cstdio"
using namespace std;
int h[100];
int n;
int num;
void swap(int x,int y)
{
int t;
t=h[x];
h[x]=h[y];
h[y]=t;
}
void siftdown(int i) //构建最大数的siftdown下沉函数
{
int t,flag=0;
while(i*2<=n&&flag==0)
{
if(h<h[i*2])
{
t=2*i;
}
else
{
t=i;
}
if(i*2+1<=n)
{
if(h[t]<h[i*2+1])
{
t=2*i+1;
}
}
if(t!=i)
{
swap(t,i);
i=t;
}
else
{
flag=1;
}
}
}
void heapsort() //heapsort堆排序函数
{
while(n>1)
{
swap(1,n);
n--; //这三句的目的是将最大的元素不断从堆顶有序的排列到堆尾,以便最后进行整体输出
siftdown(1);
}
}
int main()
{
cin>>n;
num=n;
for(int i=1;i<=n;i++)
{
scanf("%d",&h);
}
for(int i=n/2;i>=1;i--)
{
siftdown(i);
}
heapsort();
for(int i=1;i<=num;i++)
{
printf("%d ",h);
}
return 0;
}
|
|