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;
}