7-1 排序 (25 分)
给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:只有1个元素;
- 数据2:11个不相同的整数,测试基本正确性;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
- 数据6:105个顺序整数;
- 数据7:105个逆序整数;
- 数据8:105个基本有序的整数;
- 数据9:105个随机正整数,每个数字不超过1000。
输入格式:
输入第一行给出正整数N(≤105),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。
输出格式:
在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。
输入样例:
11 4 981 10 -17 0 -20 29 50 8 43 -5
输出样例:
-20 -17 -5 0 4 8 10 29 43 50 981
通过这个题对冒泡、选择、直接插入、折半插入排序做了个小结。
但对于这个题冒泡和选择会超时,两种插入排序可以用。
如果只是为了应付,这个题 sort(a,a+n); 就能AC。
代码中加了注释,想更好的理解这四种排序方法,可以打开注释中的“ 测试Print() ”,研究一下每进行一步,序列的变化,有助于理解代码和算法。
#include <set> #include <map> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> #define clr(str,x) memset(str,x,sizeof(str)) #define FRER() freopen("in.txt","r",stdin); #define FREW() freopen("out.txt","w",stdout); #define MAX_INF 0x7fffffff #define INF 0x3f3f3f3f #define maxn 100010 typedef long long int ll; using namespace std; int a[maxn]; int n; void Print() { for(int i=0; i<n; i++) { if(!i) printf("%d",a[i]); else printf(" %d",a[i]); } printf("\n"); } /*选择排序:(O(n^2)) * 每次找出子数组中最小的元素,和子数组最前面的元素换位置 */ void SelectionSort() { int Min,temp; for(int i=0; i<n-1; i++) { Min = i; for(int j=i+1; j<n; j++) { if(a[j]<a[Min]) Min=j; } if(i!=Min) { temp = a[i]; a[i] = a[Min]; a[Min] = temp; } //测试用 //Print(); } } /*冒泡排序:(O(n^2)) * 比较两个相邻的元素,将值大的元素交换至右端。 */ void BubbleSort() { for(int i=0; i<n-1; i++) //外层循环控制排序趟数 { for(int j=0; j<n-1-i; j++) //内层循环控制每一趟排序多少次 { if(a[j]>a[j+1]) { int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } //测试用 //Print(); } } /*直接插入排序:(O(n^2)) * 把n个待排序的元素看成一个有序表和一个无序表, * 开始时有序表中只有一个元素,无序表中有n-1个元素; * 排序过程即每次从无序表中取出第一个元素,将它插入到有序表中,使之成为新的有序表, * 重复n-1次完成整个排序过程。 */ void InsertSort() { //从下标为1开始比较,直到数组的末尾 for(int i=1; i<n; i++) { int j; //将要比较的元素,拿出待比较过后再插入数组 int temp = a[i]; //一次与前一元素比较,如果前一元素比要插入的元素大,则互换位置 for(j=i-1; j>=0&&a[j]>temp; j--) { a[j+1] = a[j]; } //将比较的元素插入 a[j+1] = temp; //测试用 //Print(); } } /*折半插入排序:(O(n^2)) * 折半插入排序与直接插入排序类似。 * 不同点在于折半插入利用了二分查找,直接插入是一个个地比较查找。 */ void BinaryInsertSort() { for(int i=1; i<n; i++) { int temp = a[i]; int low = 0,high = i - 1, j; while(low<=high) { int mid = (high+low)/2; if(a[mid]>temp) high = mid -1; else low = mid + 1; } for(j=i-1; j>=low; j--) { a[j+1] = a[j]; } a[low] = temp; //测试用 //Print(); } } int main() { //FRER() //FREW() scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); } /*这个题选择和冒泡排序会超时*/ //SelectionSort(); //选择排序 //BubbleSort(); //冒泡排序 /*两种插入排序不会超时*/ //InsertSort(); //直接插入排序 BinaryInsertSort(); //折半插入排序 Print(); return 0; }