动态可视化十大排序算法之冒泡排序
點擊上方藍字關注我們
提到排序算法呀,我想你肯定不陌生。這應該是學習編程時學到的第一個算法了吧。
我現在還能記得自己當時在 VC++ 6.0 上按照譚浩強老師的 C 語言教材敲出第一個冒泡排序時的激動心情。滿滿的成就感,不得不說,編程愛好者的快樂就是如此簡單。
雖然排序在我們日常生活中很常見、常用。但是對于那時的自己來說還是很難理解的。而且自己也是在對比著書修改了很多遍才正確的編譯運行。
當時我就想著要是有一個算法執行過程的動態圖那就好了。我一直也在這樣嘗試著這樣做,今天我就帶你來體驗下冒泡排序算法的動態執行過程。
話不多說,直接上干貨,先帶你看下效果,包你滿意。
不僅是簡單的算法執行過程,我還會為你介紹一些改進的技巧,讓你更加游刃有余,顯示出自己的內功修養。
有必要手動寫排序算法嗎?
可能有人覺得現在不需要自己手動寫排序算法了,用的時候直接調用編程語言內置的庫函數就行了。
在日常的工作學習中,我覺得大部分人也就是這樣做的,包括我自己在內。而且你自己寫排序算法有 Bug 不說,就算沒有 Bug,肯定也沒有編程語言內置的庫函數高效。
但是這并不能說我們不需要掌握排序算法了,我覺得主要原因有兩個吧。
掌握排序算法可以幫助我們更好的理解計算機程序的執行過程,訓練我們的編程邏輯。而且排序算法有很多變形,這些變形在特定的應用場景下會非常高效。
另外一個我覺得就是應對職場的面試了。數據結構和算法直接對應了你能不能通過筆試,進入面試。我之前做過一個互聯網大廠的筆試,筆試就是 4 道編程題,時間一個半小時。我當時一道題都沒 AC,心態直接爆炸,結果也就涼涼了。。。
冒泡排序
接下來,我們就來看一看冒泡排序算法,前面的動畫不知道你看懂了嗎?沒看懂的話可以再看一遍。
但是看懂就代表你可以寫出完整的代碼來嗎?答案并不一定哦。
話不多說,先看下代碼:
#!/usr/bin/python #?-*-?coding:UTF-8?-*- from?typing?import?List#?Bubble?Sort def?bubble_sort(array:?List[int])?->?None:for?i?in?range(len(array)?-?1):flag?=?False#?如果前面的比后面的元素大,就交換for?j?in?range(len(array)?-?1?-?i):if?array[j]?>?array[j?+?1]:array[j],?array[j?+?1]?=?array[j?+?1],?array[j]flag?=?True#?如果一輪完成,沒有一個元素進行交換,則表明元素有序,退出循環if?not?flag:breakarray?=?[3,?44,?38,?5,?47,?15] print(array) bubble_sort(array) print(array)??冒泡排序的思想就是比較相鄰之間的元素,如果?array[j] < array[j + 1],則就會互換相鄰之間的元素。這樣每輪迭代完后,總有一個元素可以到達此元素應該到達的位置。
每次到位的元素也就是第 K 大元素,舉例說,第一次到位的是第一大元素,也就是最大值。第二次到位的是第二大元素,也就是次大值。
如何評價一個排序算法?
通過上面的程序,我們就實現了冒泡排序算法,那么如何評價一個排序算法呢?我想這個你在學習數據結構與算法的時候一定都學過。
主要有以下指標:
時間復雜度
空間復雜度
穩定性
這里我就不再一一敘述了,冒泡排序算法的時間復雜度是 O(n2),空間復雜度是 O(1),是穩定的排序算法。
優化
時間復雜度是 O(n2) 的排序算法是比較耗時的,適用于小規模的數據,不適用于大規模的數據排序,那有沒有優化的方法呢?
要想從時間復雜度的量級上優化,這個就只能換排序算法了。但是呢?有一些其他的技巧,可以減少算法的運行時間。是什么呢?
就是在第奇數次迭代的時候,從前往后比較,而偶數次迭代的時候,從后往前比較。這樣雖然理論上還是 O(n2) 的時間復雜度,但是運行時間會降低不少。
#!/usr/bin/python # -*- coding: UTF-8 -*- import random import time# Bubble Sort def bubble_sort(array):for i in range(len(array) - 1):flag = Falsefor j in range(len(array) - 1 - i):if array[j] > array[j + 1]:array[j], array[j + 1] = array[j + 1], array[j]flag = Trueif not flag:breakdef optim_bubble_sort(array):for i in range(len(array) - 1):flag = Falseif i % 2:for j in range(len(array) - 1 - (i // 2), (i // 2), -1):if array[j] < array[j - 1]:array[j], array[j - 1] = array[j - 1], array[j]flag = Trueelse:for j in range((i // 2), len(array) - 1 - (i // 2)):if array[j] > array[j + 1]:array[j], array[j + 1] = array[j + 1], array[j]flag = Trueif not flag:breakif __name__ == "__main__":num = 10000array = [random.randint(0,num) for _ in range (num)]array_copy = array[:]#print(array)start = time.perf_counter()bubble_sort(array)end = time.perf_counter()#print(array)print(end - start)start = time.perf_counter()optim_bubble_sort(array_copy)end = time.perf_counter()#print(array_copy)print(end - start)從運行結果上看,運行時間還是有提高的。這是 num 設置為 10000 的時候。提前給你打個預防針,如果你?num?設置的過大,比如 100000,很有可能排序需要等20分鐘。。。
總結
冒泡排序是一種時間復雜度較高的排序算法,所以呢大部分時候都是在教科書中出現,在實際的項目或者使用過程中很少有它的身影。
但是這種思想對于剛接觸編程的人來說,還是比較容易理解的,如果上來就讓你理解遞歸,理解快排,我覺得還是比較難的。有了前面的基礎,在學習后面算法的過程中也會容易很多。
這個我覺得大多數人應該都能理解,但理解不代表掌握了。就像我在手寫這些代碼的時候還要調試一會呢,相信你也可以看到我代碼字里行間的調試信息,所以建議你花點時間自己練習下。
下篇文章我們一起學習選擇排序算法。
一個人可以走的更快,一群人可以走得更遠
長按掃碼關注我們
總結
以上是生活随笔為你收集整理的动态可视化十大排序算法之冒泡排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux学习笔记 -- 系统编程
- 下一篇: java-net-php-python-