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
/////////
/////////
思路:由於之前寫過插入排序演算法,這次就直接搬過來用了,但是這樣程式碼比較不簡潔。網上程式碼判斷是否是插入排序的思路是:先找出給出的中間序列陣列中有序部分的最後一個元素下標i,再從有序部分之後的無序序列中第一個元素開始(++i),與未排序的原陣列一 一進行比對,若直到陣列最後一個元素都完全相同,則表示,此中間序列為前半部分已排序而後半部分未排序,即為插入排序,使用sort()將原陣列的0~i進行排序(此時i是無序序列中第一個元素)。
否則就是歸併排序。由於一般的歸併排序演算法是遞迴的,因此不能直接輸出下一次排序結果,要改進演算法。此處參考了網上演算法,大意為:將原始陣列分成兩個兩個的小序列,一 一內部排序,同時將非偶數序列的尾巴部分排序;再將兩個序列合併(k=k*2,k即為小序列中的元素個數),繼續內部排序、序列尾巴排序……直到某一排序後序列與給出的中間序列相同,則再列印、進行一次歸併排序並跳出迴圈。
以下為摘抄的網上關於判斷是否是插入排序的演算法:
for( i=0; A2[i]<=A2[i+1] && i<N-1; i++ ) ; // i作為有序序列最後一個元素下標退出迴圈
for( j=++i; A1[j]==A2[j] && j<N; j++ ) ; // A1 A2從 第一個無序的元素開始 逐一比對
if( j==N ){// 前半部分有序而後半部分未改動可以確定是插入排序
cout<<"Insertion Sort"<<endl;
sort( A1, A1+i+1 );
}
//////
//////
以下是我這道題的程式碼:
#include <iostream>
#include<algorithm>
using namespace std;
int InsertSort(int oriArray[], int Array[], int n)
{
int temp;
int i,j;
int same=1;
for(i=1;i<n;i++)
{
temp = Array[i];
j = i-1;
while(j>=0 && temp<Array[j])
{
Array[j+1] = Array[j];
j = j-1;
}
Array[j+1] = temp;
//////////////////
if(same==0){
cout<<"Insertion Sort"<<endl;
for(int k=0;k<n-1;k++){
cout<<Array[k]<<" ";
}
cout<<Array[n-1];
return 1;
}
same=0;
for(int k=0;k<n;k++){
if(Array[k]!=oriArray[k])
{
same=1;
break;
}
}
}
return 0;
}
int main()
{
int n;
scanf("%d",&n);
int Array[n];
int temp[n];
int oriArray[n];
for(int i=0;i<n;i++){
scanf("%d",&Array[i]);
temp[i] = Array[i];
//oriArray[i] = Array[i];
}
for(int i=0;i<n;i++){
scanf("%d",&oriArray[i]);
}
int flag;
int f=1;
int k=1;
flag = InsertSort(oriArray, temp, n);
if(flag==0){
cout<<"Merge Sort"<<endl;
for(int i=0;i<n;i++)
{
temp[i] = Array[i];
}
while(f){
f=0;
for(int i=0;i<n;i++){
if(Array[i]!=oriArray[i]){
f=1;
break;
}
}
k = k*2;
for(int i=0;i<n/k;i++){
sort(Array+i*k,Array+(i+1)*k);
}
sort(Array+k*(n/k),Array+n);
}
for(int i=0;i<n-1;i++){
cout<<Array[i]<<" ";
}
cout<<Array[n-1];
}
return 0;
}