文章目錄
- 1.冒泡排序
- (1)基本邏輯
- (2)算法解析
- (3)完整版算法
- 1.從左向右比較,找最大值
- 2.從左向右比較,找最小值
- 3.優(yōu)化方案
- (3)時(shí)間復(fù)雜度
- (4)冒泡排序的圖形演示:
- 2.選擇排序
- (1)基本邏輯
- (2)算法分步解析
- 1.從最左邊找最小值的索引
- 2.從最右邊找最大值的索引
- (3)完整算法
- 1.從左到右查找
- 2.從右向左查找
- (4)時(shí)間復(fù)雜度
- (5)選擇排序演練
1.冒泡排序
(1)基本邏輯
冒泡排序(英語:Bubble Sort)是一種簡(jiǎn)單的排序算法。它重復(fù)地遍歷要排序的數(shù)列,一次比較兩個(gè)元素,如果他們的順序錯(cuò)誤就把他們交換過來。遍歷數(shù)列的工作是重復(fù)地進(jìn)行直到?jīng)]有再需要交換,也就是說該數(shù)列已經(jīng)排序完成。
冒泡排序算法的運(yùn)作如下:
- 從左到右,依次比較相鄰的元素。如果第一個(gè)比第二個(gè)大(升序),就交換他們兩個(gè)。
- 對(duì)每一對(duì)相鄰元素作同樣的工作,從開始第一對(duì)到結(jié)尾的最后一對(duì)。這步做完后,最右邊的元素肯定是所有數(shù)據(jù)里面的值最大的,對(duì)應(yīng)的位置為(n-1)
- 除了最右邊的一個(gè)元素,我們?cè)籴槍?duì)其他所有的元素重復(fù)以上的步驟。再循環(huán)1次,我們就能找到所有元素里面第二大的數(shù)字了,排在倒數(shù)第二個(gè)位置(n-2)
- 持續(xù)如上的操作,在我們排序n-1次的時(shí)候,就能確定n-1個(gè)元素的具體位置,剩余一個(gè)元素也肯定是最小的了。此時(shí)排序確定的元素的索引為1
如下的數(shù)據(jù),我們從左到右開始,先將相鄰的兩個(gè)元素比較,依次往右邊移動(dòng)比較,最終能找到所有數(shù)據(jù)里面最大的,如下圖所示:
- 每一次需要比較的總次數(shù),按照如下列表展示:
(2)算法解析
- 第一輪排序,找到最大值的位置需要排列到索引為n-1的位置(n為所有元素的數(shù)量)。
- 下一輪,我們就可以從索引為0開始,直到n-2之間做相鄰2個(gè)比較了
- 最后一輪是index=1的元素,比較n-1次,就你能確定n個(gè)元素的排序位置了
# 如果我們只比較一輪,把最大的值放到列表最右邊,可以如下方式
n
=
len
(
mylist
)
for
i
in
range
(
n
-
1
)
:
if
mylist
[
i
]
>
mylist
[
i
+
1
]
:
mylist
[
i
]
,
mylist
[
i
+
1
]
=
mylist
[
i
+
1
]
,
mylist
[
i
]
# 比較是從左向右開始比較的,但是最大值是放在最右邊的
(3)完整版算法
1.從左向右比較,找最大值
def
bubble_sort
(
myList
)
:
n
=
len
(
myList
)
for
j
in
range
(
n
-
1
,
0
,
-
1
)
:
# 代表從最后一個(gè)元素向左到第二個(gè)元素,不包含index=0
for
i
in
range
(
j
)
:
# j代表其他需要比較的元素的索引,數(shù)量逐步減少
if
myList
[
i
]
>
myList
[
i
+
1
]
:
myList
[
i
]
,
myList
[
i
+
1
]
=
myList
[
i
+
1
]
,
myList
[
i
]
myList
=
[
54
,
26
,
93
,
17
,
77
,
31
,
44
,
55
,
20
]
bubble_sort
(
myList
)
print
(
myList
)
# [17, 20, 26, 31, 44, 54, 55, 77, 93]
最外面循環(huán),代表找到每輪最大值的索引,從最右邊,一直正數(shù)第二個(gè)元素,對(duì)應(yīng)range(n-1, 0, -1)
里面循環(huán),代表從第一個(gè)元素,到最大元素前面的那個(gè)元素,所以用rang(0, j)表示
2.從左向右比較,找最小值
def
maoPao_min
(
alist
)
:
n
=
len
(
alist
)
for
i
in
range
(
0
,
n
-
1
)
:
for
j
in
range
(
i
+
1
,
n
)
:
if
alist
[
i
]
>
alist
[
j
]
:
alist
[
j
]
,
alist
[
i
]
=
alist
[
i
]
,
alist
[
j
]
# [17, 20, 26, 31, 44, 54, 55, 77, 93]
3.優(yōu)化方案
def
maoPao_min
(
alist
)
:
n
=
len
(
alist
)
for
i
in
range
(
0
,
n
-
1
)
:
isSorted
=
False
for
j
in
range
(
i
+
1
,
n
)
:
if
alist
[
i
]
>
alist
[
j
]
:
alist
[
j
]
,
alist
[
i
]
=
alist
[
i
]
,
alist
[
j
]
isSorted
=
True
print
(
"every time "
,
alist
)
if
not
isSorted
:
break
print
(
"result"
,
alist
)
myList
=
[
17
,
19
,
21
,
44
,
54
,
93
]
maoPao_min
(
myList
)
# every time [17, 19, 21, 44, 54, 93]
# result [17, 19, 21, 44, 54, 93]
當(dāng)排序到某個(gè)位置的時(shí)候,后面的所有其他元素排序都排好了。那么循環(huán)的話,一次都不需要置換元素,這種情況我們可以做個(gè)判斷,直接跳過所有循環(huán)即可
(3)時(shí)間復(fù)雜度
- 最優(yōu)時(shí)間復(fù)雜度:O(n) (表示遍歷一次發(fā)現(xiàn)沒有任何可以交換的元素,排序結(jié)束。)
- 最壞時(shí)間復(fù)雜度:O(n2)
- 穩(wěn)定性:穩(wěn)定
(4)冒泡排序的圖形演示:
2.選擇排序
(1)基本邏輯
選擇排序(Selection sort)是一種簡(jiǎn)單直觀的排序算法。它的工作原理如下:
- 首先,假設(shè)最左邊元素為最小值(min_index = 0)
- 其次,假設(shè)的最小值和其他元素比較,從左到右,相鄰2個(gè)元素依次比較大小,最終找到最小值的索引
- 然后,判斷假設(shè)的最小值的索引是否與真實(shí)的最小值的索引一樣,不一樣就直接互換元素的位置,這樣第一次循環(huán)就確定了所有元素中最小值的位置
- 最后,緊接著假設(shè)min_index = 1,依次重復(fù)如上步驟,找到其余元素中的最小值,直到假設(shè)的最小索引為倒數(shù)第二個(gè)元素的索引為止(倒數(shù)第二個(gè)與最后一個(gè)比較一次就結(jié)束了)
選擇排序的主要優(yōu)點(diǎn):
- 每次循環(huán)一遍,比較完所有元素之后,找到最小(大)值之后,才會(huì)互換位置,否者不會(huì)互換位置
- 如果某個(gè)元素位于正確的最終位置上,則它不會(huì)被移動(dòng)
- 如果列表為n個(gè)元素,那么所有元素最多進(jìn)行n-1次交換(每個(gè)元素都換到非自己本身的位置)
- 如果所有元素都需要移動(dòng)位置,選擇排序?qū)儆诜浅:玫囊环N
(2)算法分步解析
1.從最左邊找最小值的索引
alist
=
[
54
,
226
,
93
,
17
,
77
,
31
,
44
,
55
,
20
]
def
choiceSort
(
alist
)
:
n
=
len
(
alist
)
min_index
=
0
# 假設(shè)最左邊為最小值
for
i
in
range
(
1
,
n
)
:
# 需要拿最小索引右邊的所有元素與假設(shè)的比較
if
alist
[
min_index
]
>
alist
[
i
]
:
min_index
=
i
if
min_index
!=
0
:
alist
[
min_index
]
,
alist
[
0
]
=
alist
[
0
]
,
alist
[
min_index
]
choiceSort
(
alist
)
print
(
alist
)
# result [17, 226, 93, 54, 77, 31, 44, 55, 20]
2.從最右邊找最大值的索引
alist
=
[
54
,
226
,
93
,
17
,
77
,
31
,
44
,
55
,
20
]
def
choiceSort
(
alist
)
:
n
=
len
(
alist
)
max_index
=
n
-
1
# 假設(shè)最右邊為最大值的索引
for
i
in
range
(
n
-
2
,
-
1
,
-
1
)
:
# 需要拿倒數(shù)第二個(gè)索引,從右向左比較,直到第一個(gè)索引
if
alist
[
max_index
]
<
alist
[
i
]
:
max_index
=
i
if
max_index
!=
n
-
1
:
alist
[
max_index
]
,
alist
[
n
-
1
]
=
alist
[
n
-
1
]
,
alist
[
max_index
]
choiceSort
(
alist
)
print
(
alist
)
# result [54, 20, 93, 17, 77, 31, 44, 55, 226]
注意點(diǎn):
- 從左到右找的時(shí)候,第二個(gè)索引到最后一個(gè)索引的表達(dá)式:range(2,n-1)
- 從右向左找的時(shí)候,倒數(shù)第二個(gè)索引,到正數(shù)第一個(gè)索引的表達(dá)式:range(n-2,-1,-1)
(3)完整算法
1.從左到右查找
def
selection_sort
(
alist
)
:
n
=
len
(
alist
)
# 需要進(jìn)行n-1次選擇操作
for
i
in
range
(
n
-
1
)
:
min_index
=
i
# 記錄最小位置
for
j
in
range
(
i
+
1
,
n
)
:
# 從i+1位置到末尾選擇出最小數(shù)據(jù)
if
alist
[
j
]
<
alist
[
min_index
]
:
min_index
=
j
if
min_index
!=
i
:
alist
[
i
]
,
alist
[
min_index
]
=
alist
[
min_index
]
,
alist
[
i
]
alist
=
[
54
,
226
,
93
,
17
,
77
,
31
,
44
,
55
,
20
]
selection_sort
(
alist
)
print
(
alist
)
# [17, 20, 31, 44, 54, 55, 77, 93, 226]
2.從右向左查找
def
selection_sort
(
alist
)
:
n
=
len
(
alist
)
# 需要進(jìn)行n-1次選擇操作
for
i
in
range
(
n
-
1
,
0
,
-
1
)
:
max_index
=
i
# 記錄最大值的索引
for
j
in
range
(
i
-
1
,
-
1
,
-
1
)
:
# 從i-1位置到起始位置選擇出最大值索引
if
alist
[
j
]
>
alist
[
max_index
]
:
max_index
=
j
# 如果選擇出的數(shù)據(jù)不在正確位置,進(jìn)行交換
if
max_index
!=
i
:
alist
[
i
]
,
alist
[
max_index
]
=
alist
[
max_index
]
,
alist
[
i
]
selection_sort
(
alist
)
print
(
alist
)
# [17, 20, 31, 44, 54, 55, 77, 93, 226]
注意點(diǎn):
從左到右假設(shè)最小值索引的時(shí)候:0--------n-2, 對(duì)應(yīng)range(n-1),到倒數(shù)第二個(gè)元素
此時(shí),需要與其比較的其他數(shù)據(jù)的索引為:0+1------------n-1,對(duì)應(yīng)的range(1, n)從第二個(gè)元素到最后一個(gè)元素
從右向左排序的時(shí)候,假設(shè)最右邊為最大值索引,n-1----------1,對(duì)應(yīng)range(n-1, 0, -1)
此時(shí),需要比較的其他元素的索引為:n-2--------0,對(duì)應(yīng)的range(n-2, -1, -1)
(4)時(shí)間復(fù)雜度
- 最優(yōu)時(shí)間復(fù)雜度:O(n2)
- 最壞時(shí)間復(fù)雜度:O(n2)
- 穩(wěn)定性:不穩(wěn)定(考慮升序每次選擇最大的情況)
(5)選擇排序演練
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
