题目
读入一串整数,将其使用堆排序的方法从小到大排序,并输出。
输入
输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。
第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。
输出
只有1行,包含n个整数,表示从小到大排序完毕的所有整数。
请在每个整数后输出一个空格,并请注意行尾输出换行。
样例
输入:
10
2 8 4 6 1 10 7 3 5 9
输出:
1 2 3 4 5 6 7 8 9 10
堆排序
堆排序是指利用树这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。堆排序的和快速排序的时间复杂度相同。
向下调整
void downadjust(int low,int high)//向下调整
{
int i=low,j=i*2;
while(j<=high)
{
if(j+1<=high&&heap[j+1]<heap[j]//根据实际情况定>还是<)
j=j+1;
if(heap[j]<heap[i])//实际情况定>还是<
{
swap(heap[j],heap[i]);
i=j;
j=i*2;
}
else
break;
}
}
堆的创建
void creatheap()
{
for(int i=n/2;i>=1;i--)//从n/2开始枚举是因为:根据二叉树性质,有n/2个非叶子节点。倒着遍历是为了保证每个结点都是以其为根结点的子树中的权值最大(小)的结点。
downadjust(i,n);
}
删除堆顶元素,使最后一个元素覆盖堆顶元素,进行向下调整,保持堆的结构
void deletetop()
{
heap[1]=heap[n--];
downadjust(1,n);
}
代码
#include<bits/stdc++.h>
using namespace std;
int heap[1000010],n;
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void downadjust(int low,int high)//向下调整
{
int i=low,j=i*2;
while(j<=high)
{
if(j+1<=high&&heap[j+1]<heap[j])
j=j+1;
if(heap[j]<heap[i])
{
swap(heap[j],heap[i]);
i=j;
j=i*2;
}
else
break;
}
}
void creatheap()
{
for(int i=n/2;i>=1;i--)
downadjust(i,n);
}
void deletetop()
{
heap[1]=heap[n--];
downadjust(1,n);
}
int main()
{
int m;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>m;
heap[i]=m;
}
creatheap();
while(n!=0)
{
cout<<heap[1];
if(n>1)
cout<<" ";
deletetop();
}
}