hnust 1817 算法10-10,10-11:堆排序
题目描述
堆排序是一种利用堆结构进行排序的方法,它只需要一个记录大小的辅助空间,每个待排序的记录仅需要占用一个存储空间。
首先建立小根堆或大根堆,然后通过利用堆的性质即堆顶的元素是最小或最大值,从而依次得出每一个元素的位置。
堆排序的算法可以描述如下:
在本题中,读入一串整数,将其使用以上描述的堆排序的方法从小到大排序,并输出。
输入
输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。
第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。
输出
只有1行,包含n个整数,表示从小到大排序完毕的所有整数。
请在每个整数后输出一个空格,并请注意行尾输出换行。
样例输入 Copy
10
2 8 4 6 1 10 7 3 5 9
样例输出 Copy
1 2 3 4 5 6 7 8 9 10
提示
在本题中,需要按照题目描述中的算法完成堆排序的算法。
堆排序对于元素数较多的情况是非常有效的。通过对算法的分析,不难发现在建立含有n个元素的堆时,总共进行的关键字比较次数不会超过4n,且n个节点的堆深度是log2n数量级的。因此,堆排序在最坏情况下的时间复杂度是O(nlog2n),相对于快速排序,堆排序具有同样的时间复杂度级别,但是其不会退化。堆排序较快速排序的劣势是其常数相对较大。
解题过程
堆排序是一种利用堆数据结构的排序算法,分为两个阶段:建立堆和堆排序。
下面是对代码的详细解析:
-
头文件:
- 包含
<stdio.h>
和<string>
头文件,分别提供输入输出功能和字符串操作。
- 包含
-
命名空间:
- 使用
using namespace std;
来避免在标准库类型和函数前加std::
。
- 使用
-
常量定义:
maxn
定义了数组heap
的最大长度。
-
全局数组
heap
:- 用作堆数据结构的存储空间。
-
交换函数
swap
:- 通过引用传递参数,实现两个整数的交换。
-
下沉调整函数
downAdjust
:- 从指定位置
low
开始,到high
结束,对堆进行下沉调整,确保堆的性质。
- 从指定位置
-
创建堆函数
createheap
:- 从
n/2
开始,向下对每个节点调用downAdjust
,以构建最小堆。
- 从
-
堆排序函数
heapsort
:- 首先调用
createheap
创建最小堆。 - 然后交换堆顶元素(最小元素)和最后一个元素,减少堆的大小,并下沉调整堆。
- 首先调用
-
主函数
main
:- 读取整数
n
,直到输入结束或n
为0。 - 读取
n
个整数,存储到heap
数组中。 - 调用
heapsort
函数进行堆排序。 - 打印排序后的数组,每个数字后跟一个空格。
- 读取整数
-
程序结束:
- 输入结束后,程序返回0,表示正常结束。
代码逻辑分析:
- 这段代码首先读取要排序的数组长度
n
,然后读取n
个整数,存储到heap
数组中。 - 使用
heapsort
函数对数组进行排序,该函数首先创建一个最小堆,然后通过交换和下沉调整将元素按顺序输出。
潜在问题:
- 代码中使用了
getchar()
来读取输入中的换行符,这可能会导致在某些输入情况下出现意外行为。
改进建议:
- 考虑使用
std::cin
和std::getline
替代scanf
和getchar()
来处理输入,以提高代码的可读性和健壮性。 - 可以添加对输入数据有效性的检查,确保读取的是有效的整数。
- 考虑使用更现代的C++特性,如
std::vector
,以提高代码的灵活性。
部分代码
代码如下( 交换):
void swap(int &a,int &b){int temp;temp=a;a=b;b=temp;
}
代码如下( 对堆进行下沉调整):
void downAdjust(int low,int high){int i=low;int j=2*i;while(j<=high){if(j+1<=high&&heap[j+1]<heap[j])j++;if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=2*i;}else{break;}}
}
代码如下( 创建堆):
void createheap(int n){for(int i=n/2;i>=1;i--){downAdjust(i,n);}
}
代码如下(排序):
void heapsort(int n){createheap(n);for(int i=n;i>1;i--){swap(heap[i],heap[1]);downAdjust(1,i-1);}
}
AC代码
#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
const int maxn=100000;
int heap[maxn];
void swap(int &a,int &b){int temp;temp=a;a=b;b=temp;
}
void downAdjust(int low,int high){int i=low;int j=2*i;while(j<=high){if(j+1<=high&&heap[j+1]<heap[j])j++;if(heap[j]<heap[i]){swap(heap[i],heap[j]);i=j;j=2*i;}else{break;}}
}
void createheap(int n){for(int i=n/2;i>=1;i--){downAdjust(i,n);}
}
void heapsort(int n){createheap(n);for(int i=n;i>1;i--){swap(heap[i],heap[1]);downAdjust(1,i-1);}
}
int main()
{int n;while(scanf("%d",&n)!=EOF&&n!=0){getchar();for(int i=1;i<=n;i++){scanf("%d",&heap[i]);getchar();}heapsort(n);for(int i=n;i>0;i--){printf("%d ",heap[i]);}printf("\n");}return 0;
}