簡體   English   中英

插入排序與冒泡排序算法

[英]Insertion sort vs Bubble Sort Algorithms

我試圖了解一些排序算法,但我很難看出冒泡排序和插入排序算法的區別。

我知道兩者都是 O(n 2 ),但在我看來,冒泡排序只是在每次通過時將數組的最大值冒泡到頂部,而插入排序只是在每次通過時將最低值降低到底部。 他們不是在做完全相同的事情,只是方向不同嗎?

對於插入排序,比較/潛在交換的次數從零開始,每次都增加(即 0、1、2、3、4、...、n),但對於冒泡排序,會發生相同的行為,但在結束時排序(即 n、n-1、n-2、... 0),因為冒泡排序不再需要與排序后的最后一個元素進行比較。

盡管如此,似乎普遍認為插入排序更好。 誰能告訴我為什么?

編輯:我主要對算法工作方式的差異感興趣,而不是它們的效率或漸近復雜性。

插入排序

迭代后的第一i個元素是有序的。

在每次迭代中,下一個元素通過已排序的部分冒泡,直到它到達正確的位置:

sorted  | unsorted
1 3 5 8 | 4 6 7 9 2
1 3 4 5 8 | 6 7 9 2

將4冒泡到已排序的部分

偽代碼:

for i in 1 to n
    for j in i downto 2
        if array[j - 1] > array[j]
            swap(array[j - 1], array[j])
        else
            break

冒泡排序

迭代后的最后i個元素是最大的,並下令。

在每次迭代中,篩選未排序的部分以找到最大值。

unsorted  | biggest
3 1 5 4 2 | 6 7 8 9
1 3 4 2 | 5 6 7 8 9

5是從未分類的部分冒出來的

偽代碼:

for i in 1 to n
    for j in 1 to n - i
         if array[j] > array[j + 1]
             swap(array[j], array[j + 1])

請注意,如果在外部循環的一次迭代期間沒有進行交換,則典型的實現會提前終止(因為這意味着數組已排序)。

區別

在插入中,排序元素被冒泡到排序部分,而在冒泡排序中,最大值被排出未排序部分。

在第i次迭代的冒泡排序中,你總共有ni-1內迭代(n ^ 2)/ 2,但是在插入排序中,你在第i步上有最大的i次迭代,但平均來說是i / 2,因為你可以停止內部循環之前,在找到當前元素的正確位置之后。 所以你有(總和0到n)/ 2總共(n ^ 2)/ 4;

這就是為什么插入排序比冒泡排序更快的原因。

另一個區別,我沒有在這里看到:

冒泡排序 每個交換3個值分配 :你必須首先構建一個臨時變量以保存你想要前進的值(1號),而不是必須將另一個交換變量寫入剛保存值的位置(No.2)然后你必須在現場其他地點(3號)寫你的臨時變量。 你必須為每個點做到這一點 - 你想要前進 - 將你的變量排序到正確的位置。

使用插入排序,您可以將變量放入臨時變量中進行排序,然后將所有變量放在該位置前面1個位置,只要您到達變量的正確位置即可。 這使得每個點有1個值的分配 最后,你將臨時變量寫入現場。

這也遠遠不如價值分配。

這不是最強的速度效益,但我認為可以提及。

我希望,我表達自己可以理解,如果不是,對不起,我不是英國人

插入排序的主要優點是它是在線算法。 您不必在開始時擁有所有值。 在處理來自網絡或某些傳感器的數據時,這可能很有用。

我有一種感覺,這將比其他傳統的n log(n)算法更快。 因為復雜性將是n*(n log(n))例如從流( O(n) )讀取/存儲每個值,然后對所有值( O(n log(n))進行排序,從而得到O(n^2 log(n)) O(n log(n)) O(n^2 log(n))

相反,使用Insert Sort需要O(n)來讀取流中的值, O(n)將值放到正確的位置,因此它只是O(n^2) 其他優點是,您不需要緩沖區來存儲值,您可以在最終目標中對它們進行排序。

冒泡排序不在線(它不能在不知道將有多少項目的情況下對輸入流進行排序),因為它並不真正跟蹤已排序元素的全局最大值。 插入項目時,您需要從一開始就開始冒泡

只有當某人從一個大的數字列表中尋找前k個元素時才進行冒泡排序比插入排序更好,即在k次迭代后你將獲得前k個元素的冒泡排序。 但是,在插入排序中進行k次迭代后,它只能確保對這些k個元素進行排序。

雖然這兩種排序都是O(N ^ 2)。隱藏常量在插入排序中要小得多。隱藏常量是指實際執行的基本操作數。

插入排序有更好的運行時間?

  1. 數組幾乎已經排序 - 請注意,插入排序在這種情況下的操作比冒泡排序少。
  2. 數組的大小相對較小:插入排序你移動元素,放置當前元素。如果元素的數量很少,這只比冒泡排序更好。

請注意,插入排序並不總是比冒泡排序更好。為了充分利用兩個世界,如果數組的大小很小,可以使用插入排序,並且可能為較大的數組合並排序(或快速排序)。

在任何情況下,冒泡排序幾乎都是無用的。 在插入排序可能有太多交換的用例中,可以使用選擇排序,因為它保證少於N次交換。 因為選擇排序比冒泡排序更好,所以冒泡排序沒有用例。

插入排序:

1.在插入排序中不需要交換。

2.插入排序的時間復雜度在最佳情況下為Ω(n),在最壞情況下為O(n ^ 2)。

3.與冒泡排序相比,無復雜。

4.example:在圖書館插入書籍,安排卡片。

冒泡排序:1。冒泡排序需要等待。

2.冒泡排序的時間復雜度在最佳情況下為Ω(n),在最壞情況下為O(n ^ 2)。

3.與插入排序相比更復雜。

每次迭代中的交換次數

  • 插入排序在每次迭代中最多進行1次交換
  • 冒泡排序在每次迭代中執行0到n交換。

訪問和更改已排序的部分

  • 插入排序訪問(並在需要時進行更改)排序部分以查找考慮的數字的正確位置。
  • 優化后,Bubble-sort不會訪問已排序的內容。

在線與否

  • 插入排序在線。 這意味着插入排序放入適當位置之前一次輸入一個輸入 它不必僅比較adjacent-inputs
  • 冒泡排序不在線。 它不能一次操作一個輸入。 它在每次迭代中處理一組輸入(如果不是全部)。 冒泡排序在每次迭代中比較和交換adjacent-inputs

插入排序可以恢復為“ 查找應該在第一個位置的元素(最小值),通過移動下一個元素來創建一些空間,並將它放在第一個位置。好。現在看一下應該在第二個位置的元素。 ...... “等等......

冒泡排序操作不同,可以恢復為“ 只要我發現兩個相鄰元素的順序錯誤,我就交換它們 ”。

我將嘗試給出比其他人更簡潔和信息更豐富的答案。

是的,在每次通過之后,插入排序和冒泡排序在直覺上看起來是一樣的——它們都在邊緣構建一個排序的子列表。

但是,插入排序通常會執行較少的比較。 使用插入排序時,我們僅在每次通過時在已排序的子列表中執行線性搜索。 對於隨機數據,您可以期望進行 m/2 次比較和交換,其中 m 是已排序子列表的大小。

使用冒泡排序,我們總是在每次通過時比較未排序子列表中的每一對,所以這是 nm 比較(是隨機數據插入排序的兩倍)。 這意味着如果比較昂貴/緩慢,冒泡排序是不好的。

此外,與插入排序的交換和比較相關的分支更容易預測。 我們在進行線性插入的同時進行線性搜索,我們通常可以預測/假設線性搜索/插入將繼續進行,直到找到正確的空間。 使用冒泡排序,分支本質上是隨機的,我們可以預期有一半的時間分支未命中。 與每一個比較! 這意味着如果比較和交換相對便宜/快速,冒泡排序對流水線處理器不利。

這些因素使得冒泡排序通常比插入排序慢得多。

插入排序:我們將元素插入到數組中的適當位置,一次一個。 當我們到達數組中的第 n 個元素時,對 n-1 個元素進行排序。

冒泡排序:我們從一個元素的冒泡開始,並不斷將氣泡擴展 1,直到添加了所有元素。 在任何一次迭代中,我們只需按正確的順序交換相鄰的元素,以便在氣泡的末端獲得最大的元素。 這樣,我們一直把最大的元素放在數組的末尾,最后在所有迭代之后我們的排序就完成了。

冒泡排序和插入排序復雜度:O(n^2)

與冒泡排序相比,插入速度更快,原因如下:

插入排序只是將一個元素與一個排序數組進行比較,即第 i 個元素與包含 1...i-1 個元素的數組進行比較,這些元素已經排序。 因此,比較和交換的次數較少。 然而,在冒泡排序中,隨着冒泡的增加,比較每對鄰居的相同迭代運行。 與插入排序相比,這導致了更多的比較和交換。

因此,即使兩種算法的時間復雜度都是 O(n^2); 插入排序導致比冒泡排序更快的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM