- 1035 插入与归并 (25 分)
根据维基百科的定义:
插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。
归并排序进行如下迭代操作:首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。
现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?
输入格式:
输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。
输出格式:
首先在第 1 行中输出Insertion Sort
表示插入排序、或Merge Sort
表示归并排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。
输入样例 1:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出样例 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
输入样例 2:
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
输出样例 2:
Merge Sort 1 2 3 8 4 5 7 9 0 6
思路:自己把插入排序和归并排序实现出来,然后在排序过程中比较当前数组是否和目标数组相等,相等了再迭代一次就返回,值得一提的是可以取巧,在排序的时候使用sort内置函数来完成,就大大简短了代码长度.
另外,此题的归并排序是非递归的,排序的顺序和递归方式是不同的。
#include <iostream> #include <algorithm> using namespace std; int N; int s[105],c[105],t[105];//原数组,当前数组,用于拷贝的数组 int insert_sortt = 0;//是否是插入排序 int merge_sortt = 0;//是否是归并排序 bool judge(){ //判断两个数组是否相等 for(int i = 0;i<N;i++){ if(c[i]!=t[i]) return false; } return true; } bool insert_sort(){ //插入排序 int times = 0; for(int i = 0;i<N;i++) t[i] = s[i];//拷贝 for(int i = 1;i<=N && times<1;i++){ sort(t,t+i); if(insert_sortt) times++; //因为还要往下迭代一次 if(judge()) insert_sortt = 1;//判断 } return insert_sortt; } bool merge(){ int times = 0; for(int i = 0;i<N;i++) t[i] = s[i]; for(int i = 2;i<=N && times<1;i*=2){ //归并的规模,每次x2 for(int j = 0;j<N;j+=i){ int l = j; int r = j+i<N?j+i:N;//处理边界问题 sort(t+l,t+r); } if(merge_sortt) times++; if(judge()) merge_sortt = 1; } return merge_sortt; } int main(){ cin>>N; for(int i = 0;i<N;i++) cin>>s[i]; //输入 for(int i = 0;i<N;i++) cin>>c[i]; if(insert_sort()|| merge()) //如果是插入排序,就不用进行归并排序了。 ; if(insert_sortt == 1) cout<<"Insertion Sort"<<endl;//以下是输出 if(merge_sortt == 1) cout<<"Merge Sort"<<endl; for(int i = 0;i<N;i++){ cout<<t[i]; if(i!=N-1) cout<<" "; } return 0; }