個(gè)人網(wǎng)站做博客還是做論壇2023網(wǎng)站seo
在數(shù)據(jù)處理和算法設(shè)計(jì)中,排序是一項(xiàng)基礎(chǔ)且重要的操作。本文將介紹兩種經(jīng)典的排序算法:冒泡排序(Bubble Sort)和選擇排序(Selection Sort)。我們將通過示例代碼來演示這兩種算法如何對(duì)列表進(jìn)行升序排列。
一. 冒泡排序
冒泡排序是一種簡(jiǎn)單的排序算法,它重復(fù)地遍歷待排序的列表,比較相鄰的元素,并將順序錯(cuò)誤的元素進(jìn)行交換。這個(gè)過程會(huì)一直進(jìn)行,直到?jīng)]有需要交換的元素為止。
分析
冒泡排序是一種簡(jiǎn)單的排序算法,主要思想是通過重復(fù)遍歷待排序的列表,比較相鄰的元素并根據(jù)順序交換它們。每次遍歷后,未排序部分的最大元素會(huì)“冒泡”到列表的末尾。因此,算法得名為“冒泡排序”。
我們先拿到需要排序的列表" [ 10, 50 , 20, 60, 40, 30] " ,我們知道冒泡排序?qū)崿F(xiàn)的原理以后,可以自己在腦海里模擬計(jì)算機(jī)進(jìn)行遍歷排序:
首先,第一輪:我們先拿數(shù)列第一個(gè)數(shù)據(jù)和第二個(gè)數(shù)據(jù)比較,如果第二個(gè)數(shù)
比第一個(gè)數(shù)大,就交換兩個(gè)數(shù)據(jù)的位置。然后,然后比較第二個(gè)數(shù)與第三個(gè)
數(shù),一直到比較完整個(gè)數(shù)列,這時(shí)候,數(shù)列最小的數(shù)就已經(jīng)排在最后面了,于
是后面每輪就不需要再與最后一個(gè)數(shù)據(jù)比較了。
然后后面每一輪都和第一輪一樣,只不過每輪結(jié)束下一輪都可以少比較一個(gè)數(shù)據(jù)。
我們需要比較的列表是[ 10, 50, 20, 60, 40, 30],那么我們每輪結(jié)束以后
夠可以得到一個(gè)列表。
然后,讓我們模擬一下,每一輪結(jié)束得到的列表應(yīng)該是什么樣的:
第一輪: [50, 20, 60, 40, 30, 10]
第二輪: [50, 60, 40, 30, 20, 10]
第三輪: [60, 50, 40, 30, 20, 10] # 注意,這里我們都可以看到,其實(shí)數(shù)組的排序其實(shí)已經(jīng)完成了,
第四輪: [60, 50, 40, 30, 20, 10] # 但是計(jì)算機(jī)不是人類,它只會(huì)按照程序運(yùn)行,繼續(xù)比較。
第五輪: [60, 50, 40, 30, 20, 10]
冒泡排序的實(shí)現(xiàn)
以下是使用 Python 實(shí)現(xiàn)的冒泡排序代碼,排序列表 " [10, 50, 20, 60, 40, 30] ":
# 冒泡排序 降序,升序?qū)?#34;<"改成">"
l0 = [10, 50, 20, 60, 40, 30]
total = 0
count = 0for i in range(len(l0) - 1):for j in range(len(l0) - i - 1):total += 1 ?# 統(tǒng)計(jì)比較次數(shù)if l0[j] < l0[j + 1]: ?# 升序排序條件count += 1 ?# 統(tǒng)計(jì)交換次數(shù)temp = l0[j] ?# 交換元素l0[j] = l0[j + 1]l0[j + 1] = tempprint(f"第{i + 1}輪:{l0}")print(f"比較了{(lán)total}次,數(shù)值互換了{(lán)count}次", l0)
運(yùn)行結(jié)果
運(yùn)行上述代碼后,輸出結(jié)果如下:
第一輪: [50, 20, 60, 40, 30, 10]
第二輪: [50, 60, 40, 30, 20, 10]
第三輪: [60, 50, 40, 30, 20, 10]
第四輪: [60, 50, 40, 30, 20, 10]
第五輪: [60, 50, 40, 30, 20, 10]
比較了15次,數(shù)值互換了9次 [60, 50, 40, 30, 20, 10]
在這個(gè)例子中,我們可以看到最終的排序結(jié)果是 " [10, 20, 30, 40, 50, 60] "。在排序過程中,總共進(jìn)行了 15 次比較,其中 9 次進(jìn)行了值的交換。
二. 選擇排序
選擇排序是一種不穩(wěn)定的排序算法,它的基本思想是每一趟從未排序的部分中選擇最小(或最大)的元素,放到已排序序列的末尾,直到所有元素都排好序。這種方法的時(shí)間復(fù)雜度為 O(n^2)。
分析
選擇排序是一種簡(jiǎn)單的排序算法。它的基本思想是每次從未排序的部分中選擇最小(或最大)的元素,將其放到已排序部分的末尾。
我們先拿到需要排序的列表" [ 10, 50 , 20, 60, 40, 30] " ,我們知道選擇排序?qū)崿F(xiàn)的原理以后,就像冒泡排序一樣在腦海里模擬計(jì)算機(jī)進(jìn)行遍歷排序:
首先,我們定義一個(gè)循環(huán)外的變量"max_index"把它當(dāng)作每輪未排序最大數(shù)值的索引第一輪:我們先把數(shù)列第一個(gè)數(shù)據(jù)當(dāng)作最大值把它的索引賦予"max_index",
然后比較l0[max_index]和第二個(gè)數(shù)據(jù),如果第二個(gè)數(shù)比第一個(gè)數(shù)大,就把
第二個(gè)數(shù)的索引賦予max_index。然后,l0[max_index]與第三個(gè)數(shù)比較,
一直到比較完整個(gè)數(shù)列,這時(shí)候max_index就是數(shù)組最大數(shù)值的索引,交換
數(shù)列中第一個(gè)數(shù)值與最大數(shù)值的位置。然后后面每一輪都和第一輪一樣,只不過每輪結(jié)束下一輪都可以少比較一個(gè)數(shù)據(jù)。
我們需要比較的列表是[ 10, 50, 20, 60, 40, 30],那么我們每輪結(jié)束以后就
可以得到一個(gè)列表。
然后,讓我們模擬一下,每一輪結(jié)束得到的列表應(yīng)該是什么樣的:
第1輪:[60, 50, 20, 10, 40, 30]
第2輪:[60, 50, 20, 10, 40, 30]
第3輪:[60, 50, 40, 10, 20, 30]
第4輪:[60, 50, 40, 30, 20, 10]
第5輪:[60, 50, 40, 30, 20, 10]
選擇排序的實(shí)現(xiàn)
以下是使用 Python 實(shí)現(xiàn)的選擇排序代碼,對(duì)列表 " [60, 10, 20, 50, 40, 30] " 進(jìn)行降序排序:
# 選擇排序 降序, 升序?qū)?#34;<"改成">"
l0 = [10, 50, 20, 60, 40, 30]
total = 0
count = 0for i in range(len(l0) - 1):max_index = i # 假設(shè)未排序部分的第一個(gè)元素為最大值for j in range(i + 1, len(l0)):total += 1 # 記錄比較次數(shù)if l0[max_index] < l0[j]: # 尋找最大值max_index = jcount += 1 # 記錄交換次數(shù)# 交換當(dāng)前元素和找到的最大元素temp = l0[i]l0[i] = l0[max_index]l0[max_index] = tempprint(f"第{i + 1}輪:{l0}")print(f"比較了{(lán)total}次, 數(shù)值互換了{(lán)count}次", l0)
運(yùn)行結(jié)果
運(yùn)行上述選擇排序的代碼后,輸出結(jié)果如下:
第1輪:[60, 50, 20, 10, 40, 30]
第2輪:[60, 50, 20, 10, 40, 30]
第3輪:[60, 50, 40, 10, 20, 30]
第4輪:[60, 50, 40, 30, 20, 10]
第5輪:[60, 50, 40, 30, 20, 10]
比較了15次,數(shù)值互換了5次 [60, 50, 40, 30, 20, 10]
在這個(gè)例子中,最終的排序結(jié)果是 " [60, 50, 40, 30, 20, 10] "。在排序過程中,總共進(jìn)行了 15 次比較,一共進(jìn)行了5次值的交換。
?三. 冒泡排序與選擇排序比較
性能分析
時(shí)間復(fù)雜度:
冒泡排序的時(shí)間復(fù)雜度為 O(n2),最壞和平均情況下都是 O(n2),最佳情況下(列表已排序)為 O(n)。
選擇排序的時(shí)間復(fù)雜度也是 O(n2),無論是最壞、平均還是最佳情況都是 O(n2)。
選擇排序:
比較次數(shù):在每一輪中,選擇排序需要遍歷未排序的部分以找到最大值(或最小值)。對(duì)于長度為 (n) 的列表,第一輪需要比較 (n-1) 次,第二輪需要比較 (n-2) 次,以此類推。因此,總的比較次數(shù)為:O(n^2)
交換次數(shù):每一輪最多只進(jìn)行一次交換,因此交換次數(shù)為 (O(n))。
冒泡排序:
比較次數(shù):在每一輪中,冒泡排序需要比較相鄰的元素。對(duì)于長度為 (n) 的列表,第一輪需要比較 (n-1) 次,第二輪需要比較 (n-2) 次,以此類推??偟谋容^次數(shù)同樣為:O(n^2)
交換次數(shù):在最壞的情況下,每一次比較都需要進(jìn)行交換,因此交換次數(shù)也是 (O(n^2))。
空間復(fù)雜度:
冒泡排序是原地排序算法,空間復(fù)雜度為 O(1)。
選擇排序同樣是原地排序算法,空間復(fù)雜度也為 O(1)。
使用場(chǎng)景
冒泡排序:
1.因?yàn)槠浜?jiǎn)單易懂,適合教育和教學(xué)的場(chǎng)景,幫助初學(xué)者理解排序的基本概念。
2.不適合處理大型數(shù)據(jù)集,效率較低。
選擇排序:
1.選擇排序雖然也不適合處理大型數(shù)據(jù)集,但在某些特定情況下(例如數(shù)據(jù)基本有序時(shí)),它可能會(huì)表現(xiàn)得比冒泡排序更好。
2.適合對(duì)小型數(shù)據(jù)集進(jìn)行排序,且實(shí)現(xiàn)簡(jiǎn)單。
四. 總結(jié)
通過本文的介紹,我們了解了冒泡排序和選擇排序這兩種經(jīng)典的排序算法。雖然它們?cè)趯?shí)際應(yīng)用中并不常用(因?yàn)橛懈咝У呐判蛩惴?#xff0c;如快速排序和歸并排序),但它們?cè)趯W(xué)習(xí)算法的過程中提供了良好的基礎(chǔ)。
代碼復(fù)用在實(shí)際開發(fā)中,使用內(nèi)置的排序函數(shù)會(huì)更加高效。例如,Python 提供了內(nèi)置的? ' sort() '?方法和 ' sorted() ' 函數(shù),使用起來簡(jiǎn)單且效率高。
示例如下:
# 使用 Python 內(nèi)置的排序
l0 = [10, 50, 20, 60, 40, 30]
l0.sort() ?# 原地排序
print(l0) ?# 輸出:[10, 20, 30, 40, 50, 60]l1 = [60, 10, 20, 50, 40, 30]
sorted_l1 = sorted(l1) ?# 返回新排序的列表
print(sorted_l1) ?# 輸出:[10, 20, 30, 40, 50, 60]
希望本文能夠幫助你理解冒泡排序和選擇排序的基本概念及其實(shí)現(xiàn)。如果你有任何問題,歡迎在評(píng)論區(qū)討論!