插入排序:数列前面部分看为有序,依次将后面的无序数列元素插入到前面的有序数列中,初始状态有序数列仅有一个元素,即首元素。
归并排序:进行如下迭代操作:首先将原始序列看成N个只包含1个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下1个有序的序列。
思路
1.首先是判断排序方法,根据插入排序的特征,前面部分为已排序的,后面的与原始序列是一样的。通过这个特征来判断是否是插入排序,然后不是插入排序的即为归并排序;
2.将插入排序的序列多向后排序一位即可,用sort函数非常简单;
3.难点在于输出归并排序的下一步,首先要模拟归并排序,当然不用完全按照归并排序来做,也可以调用sort方法会简单很多,首先按照两位两位一排序,排序后,与给定数列对比,若不同,则再次排序一轮,接着再和给定的数列对比,若不同,则再排序……直到相同后,再排序一轮,然后输出即可。
可以用equal()方法比较容器中的两个区间内的元素。有3个参数first1,last1和first2。如果对于区间[first1, last1)内所有的first1+i,first1+i和first2所在位置处的元素都相等,则equal算法返回真,否则返回假。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
vector<int>origin(n),target(n);
for(int i=0;i<n;i++)
scanf("%d",&origin[i]);
for(int i=0;i<n;i++)
scanf("%d",&target[i]);
//插入排序特征:前面有序,后面与原始序列一样
//如果不是插入排序就是归并排序
//升序排列
int index;
for(int i=1;i<n;i++)
{
if(target[i]<target[i-1])
{
index=i;
break;
}
}
int flag=0;//0为插入插入排序,1为归并排序
for(int i=index;i<n;i++)
{
if(target[i]!=origin[i])
{
flag=1;
break;
}
}
if(flag==0)
{
printf("Insertion Sort\n");
sort(target.begin(),target.begin()+index+1);
printf("%d", target[0]);
for(int i=1;i<n;i++)
{
printf(" %d",target[i]);
}
}
else if(flag==1)
{
printf("Merge Sort\n");
//输出下一步
int k=1;
bool isNotEqual=true;
while(isNotEqual)
{
isNotEqual=false;
//不同进行一次归并排序
if(!equal(origin.begin(),origin.end(),target.begin()))
{
isNotEqual=true;
}
k*=2;
for(int i=0;i<n/k;i++)
{
sort(origin.begin()+i*k,origin.begin()+(i+1)*k);
}
sort(origin.begin() + k * (n / k), origin.end());
}
printf("%d", origin[0]);
for(int i = 1; i < n; ++i)
printf(" %d", origin[i]);
}
return 0;
}