排序演算法(1)插入排序的演算法分析

2021-07-15 13:43:02 字數 3902 閱讀 4974

結語

今天,我們介紹的是排序演算法經典的一種排序演算法,這個演算法是插入排序。
相信大家都玩過紙牌。插入排序的工作方式就像許多人排序一手撲克牌。

開始時,我們的左手為空並且桌子上的牌面朝下(意味著我們不在翻開之前並不知道下一張牌是多大的)。

然後,我們每次從那些牌中選出一張牌,並把它插入到正確的位置(一般我們認為左邊的最小),我們從左到右(或從右到左)將它與已在手中的每張牌進行比較。

對於插入排序,我們將偽**的過程命名為insertion-sort

其中

引數是a[1..n],為長度n的乙個需要排序的序列。

a.length表示陣列a中元素的數量

該演算法在陣列a中重排這些數,在任何時候,最多只有其中的常數個數字儲存在陣列外面。

等insertion-sort結束時,輸入陣列a包含排序好的輸出序列。

代價次數

forj=2toa.lengthc1

n

key = a[j]c2

n−1

i = j - 1c3

n−1

whilei > 0anda[i] > keyc4

∑nj=2t

j

a[i+1] = a[i]c5

∑nj=2(

tj−1

)

i = i - 1c6

∑nj=2(

tj−1

)

a[i+1]=keyc7

n−1

該演算法的執行時間是執行每條語句的執行時間之和。基於此,我們可以計算在具有n個值輸入上insertion-sort(a)的執行時間t[n],我們將代價次數列對應元素之積求和,得 t(

n)=c

1n+c

2(n−

1)+c

3(n−

1)+c

4∑j=

2ntj

+c5∑

j=2n

(tj−

1)+c

6∑j=

2n(t

j−1)

+c7(

n−1)

最好情況下:對於給定的n個需要排序的,若輸入已排序,則出現最佳情況。這個時候,對於j=2,3,….,n,可以發現,當i取初值j-1時,有a[

i]≤k

ey。從而對j=2,3,…,n有tj

=1,也就是說只需要比較一次。

我估計說到這裡,有些人看不懂,我就簡單的說吧:

假設現在你左手中的牌都是已經排好序了的,而且是從小到大排序,現在你手上拿了一張牌,比你左手上的牌最右邊(即是你手中牌中最大)還要大,那麼你一定要保證牌是從小到大的排序,必然會把牌之間放在你牌的最右邊。而這個過程,你只是和你本來有的牌的最大一張比較了一次。

所以最好的情況下的時間複雜度tn

為: t(n)

=c1n

+c2(

n−1)

+c3(

n−1)

+c4(

n−1)

+c7(

n−1)

=(c1

+c2+

c3+c

4+c7

)n−(

c1+c

2+c3

+c4)

即 t(n)

=an+

b

其中

a 和

b依賴於語句代價ci

我們可以得出乙個結論:

在最好情況下,插入排序的時間複雜度在o(

n),即線性

時間上完成排序。

最壞情況下:

若輸入陣列已方向排序,即按照遞減排序排好了序,則導致最壞情況。我們必須把每個元素a[j]與整個已排序子陣列a[1..j-1]中的每個元素都要進行比較,所以對j=2,3,…,n,有tj=j。

我估計有人問為什麼tj

=j,那麼我就這樣告訴你吧:tj

是while語句進行比較語句的執行的次數,最後一次是進行i>0的判斷,所以a[1..j-1]與a[j]實際上進行了j-1次比較,那麼為什麼進行j-1次比較呢,我們這麼想,j代表我要加入第幾張牌,我就以j=3來說,我即將加入第3張牌進入我左手的牌中(左手有兩張牌,已經公升序排列了好了),而這個牌比前面2個都要小,那麼我是需要和比較兩次才知道的,所以一共比較j-1次。

值得注意的是,這時候的

∑j=2

nj=n

(n+1

)2−1

以及 ∑j

=2n(

j−1)

=n(n

−1)2

上述是求和遞推公式,我並不會給予證明,畢竟這可不是數學教學。

所以最壞的情況下的時間複雜度tn

為: t(n)

=c1n

+c2(

n−1)

+c3(

n−1)

+c4(

n(n+

1)2−

1)+c

5(n(

n−1)

2)+c

6(n(

n−1)

2)+c

7(n−

1)=(

c42+

c52+

c62)

n2+(

c1+c

2+c3

+c42

−c52

−c62

+c7)

n−(c

2+c3

+c4+

c7)

即 t(

n)=a

n2+b

n+c

其中

a 、b和

c 依賴於語句代價ci

我們可以得出乙個結論:

在最壞情況下,插入排序的時間複雜度在o(

n2) ,即n的

二次函式

上完成排序。

平均情況和最壞情況差不多,複雜度也在o(

n2)

接下來,我將會在下一文中編寫出語言版本去實現演算法。敬請期待。

排序演算法(1) 插入排序

輸入 n個數的乙個序列 a1,a2 an 輸出 輸入序列的乙個排序 a1,a2,an 滿足a1 a2 an。首先,對於少量元素的排序,插入排序是一種有效的演算法。舉個生動的例子,插入排序就像我們手裡剛剛分到的撲克牌,亂序。我們會將排由左到右進行整理,由小到大排序。待排序列 5 4 3 9 7 5 3...

排序演算法1 插入排序

插入排序思想 每一步將乙個待排序的元素,按期排序碼的大小,插入到前面已經排好序的一組元素的合適位置上去,知道元素插完。插入排序分為直接插入排序,和優化後的二分插入排序,我們先看第一種 基本思想 當我們插入第i i 1 個元素時,前面的所有元素已經排好序,此時我們使用當前元素從後向前比較,直到找到乙個...

排序演算法 1 插入排序

插入排序的過程和平時打牌的時候給手裡的牌排序差不多 從牌桌上抽一張牌 把抽到的牌從右到左 或者從左到右 挨個和手裡的牌進行比較,當發現左邊的牌大一些,右邊的牌小一些,就將牌插入到該位置 重複執行步驟1,直到牌抽完了 include include 對範圍 first,last 的元素進行插入排序 p...