PAT乙級 1035 插入與歸併

2021-08-31 20:58:11 字數 1695 閱讀 8277

根據維基百科的定義:

插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。

歸併排序進行如下迭代操作:首先將原始序列看成 n 個只包含 1 個元素的有序子串行,然後每次迭代歸併兩個相鄰的有序子串行,直到最後只剩下 1 個有序的序列。

現給定原始序列和由某排序演算法產生的中間序列,請你判斷該演算法究竟是哪種排序演算法?

輸入在第一行給出正整數 n (≤100);隨後一行給出原始序列的 n 個整數;最後一行給出由某排序演算法產生的中間序列。這裡假設排序的目標序列是公升序。數字間以空格分隔。

首先在第 1 行中輸出insertion sort表示插入排序、或merge sort表示歸併排序;然後在第 2 行中輸出用該排序演算法再迭代一輪的結果序列。題目保證每組測試的結果是唯一的。數字間以空格分隔,且行首尾不得有多餘空格。

103 1 2 8 7 5 9 4 6 0

1 2 3 7 8 5 9 4 6 0

insertion sort

1 2 3 5 7 8 9 4 6 0

103 1 2 8 7 5 9 4 0 6

1 3 2 8 5 7 4 9 0 6

merge sort

1 2 3 8 4 5 7 9 0 6

解題過程比較曲折,寫的比較混亂,不想看的可以直接跳到「第二次修改」。

本來想寫出插入排序與歸併排序的演算法,然後排序一次比較一次,插入排序順利的實現了,但遞迴的歸併排序的執行機制與題目要求並不同,而是先排左側再排右側,並且當子列有奇數個元素時並不會實現兩兩歸併,因此改變思路是必須的。

新的思路是這樣的:如果從中間序列的頭部開始,有長度為l的一段有序子列,若中間序列的剩餘部分的元素與原始序列相同位置的元素全部相同,則可判定為插入排序,對中間序列長度為l+1的一段排序並輸出即可;否則為歸併排序,此時對每個長度為2l的子串行進行排序,如果2l大於總長度n,則對整個序列進行排序。 劃去的這一部分會出現這樣的問題:比如說對序列3、2、5、4、9、7、6、1,在進行一輪歸併後變為2、3、4、5、7、9、1、6,實際上此時l應該為2,但這樣得到的卻是6。

如上所述,並不能直接對中間序列排序,而應該對原始序列排序,直至與中間序列相同。顯然此時又回到了開始時的思路…但這時我已經掌握了借助快排實現非遞迴歸併排序的方法,因此順利完成了問題。

這次修改沒有改變對插入方法的判斷的標準,但改回了一開始的策略,即每排序一次比較一次,相同時則再排序一次並輸出。最最最開始時針對插入排序做過一次測試,當時測試點4是通過的,改方法之後一直無法通過,不想再找原因了,做了好多天,很痛苦…於是在掌握了歸併排序的基礎上,又將插入排序改了回去。

#includevoid quick_sort(int s,int l,int r){//快排

if(l=x) // 從右向左找第乙個小於x的數

PAT 乙級 1035 插入與歸併

1.題目描述 根據維基百科的定義 插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。歸併排序進行如下迭代操作 首先將原始序列看成n個只包含1個元素的有序子串行,然後每次迭代歸併兩個相鄰的有...

PAT乙級 1035插入與歸併

根據維基百科的定義 現給定原始序列和由某排序演算法產生的中間序列,請你判斷該演算法究竟是哪種排序演算法?輸入在第一行給出正整數 n 100 隨後一行給出原始序列的 n 個整數 最後一行給出由某排序演算法產生的中間序列。這裡假設排序的目標序列是公升序。數字間以空格分隔。首先在第 1 行中輸出inser...

PAT 乙級 1035( 插入與歸併 )

根據維基百科的定義 插入排序是迭代演算法,逐一獲得輸入資料,逐步產生有序的輸出序列。每步迭代中,演算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。歸併排序進行如下迭代操作 首先將原始序列看成 n 個只包含 1 個元素的有序子串行,然後每次迭代歸併兩個相鄰的有序子串...