1089. Insert or Merge (25)

PAT-A,題目地址:https://www.patest.cn/contests/pat-a-practise/1089

思路:

  1. 這道題首先要判斷清楚用的是哪種排序,顯然,驗證插入排序要簡單一些,通過sample就可以觀察出,插入排序到一半時,前若干個元素是從大到小排列的,然后之后的元素都在其初始的位置。如果滿足這個規律,就是插入排序,否則就是歸并排序
  2. 如果是插入排序,先找出所有n個元素中,已經排好序的有insert_stage個,然后對于第insert_stage+1個元素,給其找個合適的位置,然后依次輸出即可
  3. 如果是歸并排序,則要找出歸并到了第幾步,即當前已經sorted的數組的大小是多少,然后把這個數字擴大一倍,進行歸并,這里我比較偷懶,用了sort函數

代碼

#include <iostream>
#include <algorithm>

using namespace std;

int main(){
    int n;
    int init[100]; //初始數組
    int inter[100]; //排序到一半的數組
    bool is_merge = false;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> init[i];
    }
    for(int i = 0; i < n; i++){
        cin >> inter[i];
    }
    int insert_stage = 1;
    for(int i = 1; i < n; i++){
        if(inter[i] >= inter[i-1]);
        else{
            insert_stage = i; //有insert_stage個數是已經排好序的
            break;
        }
    }
    for(int i = insert_stage; i < n; i++){ //在此之后的數必須還處于原來的位置
        if(inter[i] == init[i]);
        else{
            is_merge = true;
            break;
        }
    }
    if(!is_merge){ //如果是插入排序
        cout << "Insertion Sort" << endl;
        int index = 0;
        for(int i = 0; i < n; i++){
            if(inter[i] < inter[insert_stage])
                cout << inter[i] << " ";
            else{
                index = i; //下一步要把下標為index的數插入到sorted的數組中
                break;
            }
        }
        cout << inter[insert_stage] << " ";
        for(int i = index; i < insert_stage; i++){
            cout << inter[i];
            if(i != n-1)
                cout << " ";
        }
        for(int i = insert_stage + 1; i < n; i++){ //剩下的還未排序的數
            cout << inter[i];
            if(i != n-1)
                cout << " ";
        }
        cout << endl;
    }
    else{ //如果是歸并排序
        cout << "Merge Sort" << endl;
        bool right = true;
        int group_size = 64;
        while(group_size > n)
            group_size /= 2;
        while(1){
            int round = n / group_size + 1;
            right = true; //排好序的數組大小是不是groug_size
            for(int i = 0; i < round; i++){
                for(int j = i * group_size; j < n && j < (i+1) * group_size; j++){
                    if(j == i * group_size || inter[j] > inter[j-1]); //組內是不是sorted
                    else{
                        right = false;
                        break;
                    }
                }
                if(!right)
                    break;
            }
            if(right || group_size == 1)
                break;
            group_size /= 2;
        }
        group_size *= 2; //把group_size擴大一倍。代表下一步排好序的數組大小
        int round = n / group_size + 1;
        for(int i = 0; i < round; i++){ //對每個子數組進行歸并
            int start = i * group_size;
            int end = n < (i+1) * group_size ? n : (i+1) * group_size;
            sort(&inter[start], &inter[end]);
        }
        for(int i = 0; i < n; i++){
            cout << inter[i];
            if(i != n-1)
                cout << " ";
        }
        cout << endl;
    }

    return 0;
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 總結一下常見的排序算法。 排序分內排序和外排序。內排序:指在排序期間數據對象全部存放在內存的排序。外排序:指在排序...
    jiangliang閱讀 1,375評論 0 1
  • 一、 單項選擇題(共71題) 對n個元素的序列進行冒泡排序時,最少的比較次數是( )。A. n ...
    貝影閱讀 9,206評論 0 10
  • 因為之前就復習完數據結構了,所以為了保持記憶,整理了一份復習綱要,復習的時候可以看著綱要想具體內容。 樹 樹的基本...
    牛富貴兒閱讀 6,989評論 3 10
  • 概述:排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,742評論 0 15
  • 美好,就在我們身邊 我喜歡拍照,將美好的事物定格。 如果說自己愛好攝影,實覺自己附庸風雅。我沒有高端的設備,也沒有...
    5780933168ec閱讀 288評論 0 6