这道题主要就是插入排序和归并排序,如果你对这两个排序很熟悉的话,就很简单,但是如果你和我一样还很菜鸡,连插入排序和归并排序的算法都没法代码实现的话,就只能抱着一本算法书,照着书上抄代码了,即便如此也是很麻烦的。
在写的过程中,会发现“判断两数组是否相同”以及“输出数组”这两个操作在插入排序和归并排序中都需要用到,所以写成函数放在外面会使代码显得精简很多。此外,就是一些小细节了,譬如,题意是不考虑初始数组的,以及题目的规模比较小在归并排序的时候没有必要写merge函数,直接sort会方便很多,最后就是先插入判断在归并,当然你也可以不这样,函数调用直接的衔接也很重要。
自己写的时候还有一个地方处理的不好,是看了题解再改的,在判断出是那种排序后还需要输出该排序下一次迭代后的结果,这其实直接写是很不方便的,尽管是可行的,实际上好的方法就是每次先判断再迭代一次,之后再考虑要不要输出,这样的话就算要输出也可以直接输出了!
using namespace std;
#include<bits/stdc++.h>
int origin[100],temp[100],changed[100];
int n;
bool isSame(int a[],int b[]){//写成函数调用会使代码简洁很多
for(int i=0;i<n;i++){
if(a[i] != b[i]) return false;
}
return true;
}
bool showArray(int a[]){//写成函数调用会使代码简洁很多
for(int i=0;i<n;i++){
printf("%d",a[i]);
if(i<n-1) printf(" ");
}
}
bool insertSort(){
bool flag=false;
for(int i=1;i<n;i++){
if(i!=1 && isSame(temp,changed)){i!=1不考虑初始序列
flag=true;
}
int tmp=temp[i],j=i;
while(j>0 && tmp<temp[j-1]){
temp[j]=temp[j-1];
j--;
}
temp[j]=tmp;
if(flag){
return true;
}
}
return false;
}
void mergeSort(){
bool flag=false;
for(int step=2;step/2<=n;step*=2){
if(step!=2 && isSame(temp,changed)){//step!=2不考虑初始序列
flag=true;
}
for(int i=0;i<n;i+=step){
//问题规模不大可以直接调用sort,更方便,但要注意参数值
sort(temp+i,temp+min(i+step,n));
}
if(flag){
showArray(temp);
return ;
}
}
}
int main(){
int i;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&origin[i]);
temp[i]=origin[i];
}
for(i=0;i<n;i++){
scanf("%d",&changed[i]);
}
if(insertSort()){
printf("Insertion Sort\n");
showArray(temp);
}
else{
printf("Merge Sort\n");
for(i=0;i<n;i++) temp[i]=origin[i];
mergeSort();
}
return 0;
}