1. 什麼是冒泡排序
冒泡排序是把一個由同類型元素組成的序列(如數字組成的列表)中的元素按照一定順序(升序或者降序)依次排列的方法。
實現方式是將序列的第一對(可以使倒數第一對,也可以正數第一對,自己根據需要定義)元素進行比較,決定較大的放在左邊(降序排列)或者右邊(升序排列),然後依次進行第二對元素的比較,然後根據大小決定是否交換位置,依次類推,如果按照升序排列,那麼最後一個數就是最大數。
下圖將數列[1,5,2,3,4]
進行升序排序,詳細過程如下:
2. 程序實現原理
- 通過等差數列求和公式計算需要循環多少次。
- 設置變量用於定位元素索引位置,該變量可以實現自加1
- 通過if/elif/else 判斷是否交換位置、判斷是否完成某個新數列的排序、恢復位置索引
- 完成排序,打印新數列
一定要理解上圖中所講的新數列是什麼意思,後文將用到新數列的說法
僞代碼如下:
序列爲 = [1,5,2,3,4]
索引1 用於定位一對數的前者 = 0
索引2 用於定位一對數的後者 = 1
索引3 用戶定位新數列需要比較的元素= 1
需要執行的循環次數 = (4*(1+4))/2=10
for _ in range(10+序列元素數量-2): 本來應該用for循環10次,但是在下面的if判斷中,會由於索引越界浪費(元素數量-1(也就是新數列個數))次機會再排除最後一次越界,所以10+序列元素數量-1-1
if (序列索引1的元素 <= 序列索引2的元素) 且 序列索引2 <= 序列最大索引(元素個數-索引3):
什麼也不做,因爲左邊元素不大於右邊元素,但是這次索引變量要自加1,進行下一對元素的比較
索引1 += 1
索引2 += 1
elif (序列索引1的元素 > 序列索引2的元素) 且 序列索引2 <= 序列最大索引(元素個數-索引3):
序列索引1的元素 和 序列索引2的元素 交換位置
索引1 += 1
索引2 += 1
else:執行到這一步 就說明已經完成某個序列中最大數的排序,恢復索引默認值對新數列進行排序
索引1 = 0
索引2 = 0
索引3 += 1 新數列最後一位數不用進行排序,因爲已經完成了
最後打印排序完成的序列
3. Python 代碼實現(低級版本)
基於以上實現原理,用python代碼實現如下:
nums=[1,5,2,4,3]
index1 = 0
index2 = 1
index3 = 1
times = 1 # 用於打印標記運行次數,可有可無,不影響功
sum_count = ((len(nums)-1)*(1+len(nums)-1))//2 # 等差數列求和公式
print("數列 {0:},共 {1:} 個元素,需要進行 {2:} 次排序,過程中將對 {3:} 個新數列排序\n".format(nums,len(nums),sum_count,len(nums)-1))
for _ in range(sum_count+len(nums)-1): #用for循環xx次
if index2<=len(nums)-index3 and nums[index1] <= nums[index2] :
print("Seq {0:}:".format(times),nums[index1],"--->",nums[index2],":不換位","--> 新數列爲 {0:}".format(nums))
index1 += 1
index2 += 1
times += 1
elif index2<=len(nums)-index3 and nums[index1] > nums[index2]:
nums[index1],nums[index2] = nums[index2],nums[index1]
print("Seq {0:}:".format(times),nums[index2],"--->",nums[index1],":換位","--> 新數列爲 {0:}".format(nums))
index1 += 1
index2 += 1
times += 1
else:
print("Seq {0:}: 完成對元素 {1:} 的排序,接下來對數列 {2:} 排序".format(times-1,nums[len(nums)-index3],nums[:len(nums)-index3]))
index1 = 0
index2 = 1
index3 += 1
print("數列升序排列後爲: ",nums)
運行結果如下:
數列 [1, 5, 2, 4, 3],共 5 個元素,需要進行 10 次排序,過程中將對 4 個新數列排序
Seq 1: 1 ---> 5 :不換位 --> 新數列爲 [1, 5, 2, 4, 3]
Seq 2: 5 ---> 2 :換位 --> 新數列爲 [1, 2, 5, 4, 3]
Seq 3: 5 ---> 4 :換位 --> 新數列爲 [1, 2, 4, 5, 3]
Seq 4: 5 ---> 3 :換位 --> 新數列爲 [1, 2, 4, 3, 5]
Seq 4: 完成對元素 5 的排序,接下來對數列 [1, 2, 4, 3] 排序
Seq 5: 1 ---> 2 :不換位 --> 新數列爲 [1, 2, 4, 3, 5]
Seq 6: 2 ---> 4 :不換位 --> 新數列爲 [1, 2, 4, 3, 5]
Seq 7: 4 ---> 3 :換位 --> 新數列爲 [1, 2, 3, 4, 5]
Seq 7: 完成對元素 4 的排序,接下來對數列 [1, 2, 3] 排序
Seq 8: 1 ---> 2 :不換位 --> 新數列爲 [1, 2, 3, 4, 5]
Seq 9: 2 ---> 3 :不換位 --> 新數列爲 [1, 2, 3, 4, 5]
Seq 9: 完成對元素 3 的排序,接下來對數列 [1, 2] 排序
Seq 10: 1 ---> 2 :不換位 --> 新數列爲 [1, 2, 3, 4, 5]
Seq 10: 完成對元素 2 的排序,接下來對數列 [1] 排序
數列升序排列後爲: [1, 2, 3, 4, 5]
4. Python 代碼實現(高級版本)
用for迭代實現冒泡排序,代碼簡單,邏輯性強:
import random,datetime
nums =[random.randint(0,1000) for _ in range (150) ] #生成150個隨機0-1000範圍內的隨機整數組成的列表,用於排序
for i in range(len(nums) - 1): # 這個循環負責設置冒泡排序進行的次數,也就是新數列的個數
for j in range(len(nums) - i - 1): # 對每個新數列進行排序
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
print(nums)
該代碼的運算速度是基本版本的2.5倍。