1035 插入与归并
第一种方法。
直接模拟插入排序和非递归的归并排序。。。
#include<iostream> #include<algorithm> using namespace std; int n; int a[111] = {0},b[111]= {0},temp[111] = {0}; bool flag = false;//表示是否和中间序列相同 bool isSame() {//判断当前序列与中间序列是否相同 for(int i =1; i <= n; ++i) if(a[i] != b[i]) return false; return true; } void print(int t) {//打印结果 if(t == 0) printf("Insertion Sort\n"); else if(t == 1)printf("Merge Sort\n"); else ; for(int i = 1; i <= n; ++i) { cout<<a[i]; if(i < n) printf(" "); } printf("\n"); } void insertSort() {//插入排序,升序 for(int i = 2; i <= n; ++i) { if(a[i] < a[i-1] ) { //当前的元素小于前面的元素 int j = i; a[0] = a[i];//设置哨兵 while(a[j-1] > a[0]) { a[j] = a[j-1]; --j; } a[j] = a[0]; } if(isSame() && flag == false) { flag = true; continue; } if(flag == true) { print(0); return ; } } } void mergeSort() {//非递归的归并排序,可以求出每一趟排序结束后的序列 for(int step = 2; step/2 <= n; step*=2) { //每step个元素为一组 for(int i = 1; i <= n; i+=step)//下标从1开始,对每组step升序排序 sort(a+i,a+min(i+step,n+1)); if(isSame() && flag == false) { flag = true; continue; } if(flag == true) { print(1); return ; } } } int main() { cin>>n; for(int i = 1; i <= n; ++i) { //输入原始序列 cin>>a[i]; temp[i] = a[i]; } for(int i = 1; i <= n; ++i)//输入中间序列 cin>>b[i]; insertSort();//插入排序 if(flag == false) { for(int i = 1; i <= n; ++i) //恢复原始序列 a[i] = temp[i]; mergeSort();//非递归的归并排序 } return 0; }
第二种方法。
一,对于插入排序。
原始序列:3 1 2 8 7 5 9 4 6 0
中间序列:1 2 3 7 8 5 9 4 6 0
发现标红的序列已经有序,并且中间序列与原始序列的未标红部分全部相同,说明这是插入排序。
原始序列:3 1 2 8 7 5 9 4 0 6
中间序列:1 3 2 8 5 7 4 9 0 6
发现标红的序列已经有序,并且中间序列与原始序列的未标红部分不完全相同,说明这不是插入排序。
二,非递归的归并排序和第一种方法的一样。
注意点:
一,原始序列可能存在多个相同的元素,所以第12行代码的判断条件,必须写成b[i] <= b[i+1], 否则测试点4无法通过 。
#include<iostream> #include<algorithm> using namespace std; int main() { int n,a[111]= {0},b[111]= {0},i,j; cin>>n; for(i = 1; i <= n; ++i)//输入原始序列 cin>>a[i]; for(i = 1; i <= n; ++i)//输入中间序列 cin>>b[i]; for(i = 1; i < n && b[i] <= b[i+1]; ++i); //找到中间序列的有序区的最后一个元素的下标 for(j = i+1; j <= n && b[j] == a[j]; ++j);//从中间序列的无序区的第一个元素下标j开始,与同一下标开始的原始序列的元素逐一比较 if(j > n) {//比较结束,且每个元素都相同,说明时是插入排序 printf("Insertion Sort\n"); sort(b+1,b+min(i+2,n+1));//再迭代一轮 for(i = 1; i <= n; ++i) { if(i > 1) printf(" "); cout<<b[i]; } } else { printf("Merge Sort\n"); for(int step = 2; step/2 <= n; step *= 2) { for(i = 1; i <= n; i+=step) sort(a+i,a+min(i+step,n+1)); //必须这么写 for(i = 1; i <= n; ++i) if(a[i] != b[i]) break; if(i > n) { //再迭代一轮 step *= 2; for(i = 1; i <= n; i+=step) sort(a+i,a+min(i+step,n+1)); for(int i = 1; i <= n; ++i) { if(i > 1) printf(" "); cout<<a[i]; } return 0; } } } return 0; }