1. 程式人生 > >1035. 插入與歸併(25)

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;
}