代码
#include <iostream>
#include <algorithm>
using namespace std;
void insertSort(int a[], int i, int n) {
int t = a[i];
for(int j=0; j<i; j++) {
if(a[j]>t) {
for(int k=i-1; k>=j; k--) {
a[k+1] = a[k];
}
a[j] = t;
break;
}
}
}
void mergeSort(int a[], int i, int n) {
for(int j=0; j<n; j+=i) {
sort(a+j, j+i<n?a+j+i:a+n);
}
}
bool isSame(int a[], int b[], int n) {
bool flag = true;
for(int i=0; i<n; i++) {
if(a[i]!=b[i]) {
flag = false;
break;
}
}
return flag;
}
void output(int a[], int n) {
cout<<a[0];
for(int i=1; i<n; i++) {
cout<<" "<<a[i];
}
cout<<endl;
}
int main() {
int n;
cin>>n;
int a[n];
int b[n];
int insert[n];
int merge[n];
for(int i=0; i<n; i++) {
cin>>a[i];
insert[i] = a[i];
merge[i] = a[i];
}
for(int i=0; i<n; i++) {
cin>>b[i];
}
bool flag = true;
for(int i=1; i<n; i++) {
insertSort(insert, i, n);
if(isSame(insert, b, n)) {
insertSort(insert, i+1, n);
cout<<"Insertion Sort"<<endl;
output(insert, n);
flag = false;
break;
}
}
if(flag) {
for(int i=1; i<n; i*=2) {
mergeSort(merge, i, n);
if(isSame(merge, b, n)) {
mergeSort(merge, i*2, n);
cout<<"Merge Sort"<<endl;
output(merge, n);
break;
}
}
}
return 0;
}
注解
1、首先必须理解插入排序和归并排序的思想。
插入排序:将数组分为有序堆和无序堆两部分,拿到一个数后,把该数插入到有序堆中的合适位置,依次进行,直到所有元素都在有序堆。
归并排序:n路归并排序,以n=2为例,第一轮是每个元素单独看成一堆,堆内排序。第二轮,2个元素看成一堆。第三轮,2*2个元素看成一堆。以此类推,直到所有元素变成1堆。n路就是把2换成n即可。
2、i路归并排序代码:其中sort函数是调用了algorithm中的排序函数。
void mergeSort(int a[], int i, int n) {
for(int j=0; j<n; j+=i) {
sort(a+j, j+i<n?a+j+i:a+n);
}
}
3、插入排序代码:(把a[i]插入到有序堆)
void insertSort(int a[], int i, int n) {
int t = a[i];
for(int j=0; j<i; j++) {
if(a[j]>t) {
for(int k=i-1; k>=j; k--) {
a[k+1] = a[k];
}
a[j] = t;
break;
}
}
}
4、本题目有个小坑点,就是代码中的flag,如果不设置flag,有一个case会出现Wrong Answer。分析原因就是可能有一组案例是插入、归并均可出现的,但题目中的正确输出是Insertion Sort。可以试着找找这样的case?