有一個衝動:重溫Python交換排序算法之冒泡排序

Python冒泡交換排序的思想

  • 相鄰元素兩兩比較大小,有必要則交換。
  • 元素越小或越大,就會在數列中慢慢的交換並“浮”向頂端,如同水泡咕嘟咕嘟往上冒。

排序算法,一般都實現爲就地排序,輸出爲升序;

  • 擴大有序區,減小無序區。圖中紅色部分就是增大的有序區,反之就是減小的無序區
  • 每一趟比較中,將無序區中所有元素依次兩兩比較,升序排序將大數調整到兩數中的右側
  • 每一趟比較完成,都會把這一趟的最大數推倒當前無序區的最右側

Python冒泡排序算法v1.1

基本實現
思考時,將問題規模減小,一般2次不一定能找到規律,3次基本上可以看出規律。所以,我們思考時認
爲列表裏面就只有4個元素。

nums = [5, 1, 4, 2, 8] 

count= 0
swap_count =0
# 輔助評估算法: count表示比較的次數,count_swap表示交換的次數

for i in range(len(nums)-1):   # i 控制趟數

    # 本趟內兩兩比較,大數換到右邊-->>>

    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:  # 只有大於才交換,小於等於就不用了
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1            
print(nums)
print("本版本問題:沒有考慮提前結束的情況,導致比較次數爲",count,"次")
print("本Python冒泡排序算法版本,交換次數",swap_count)


# 如果某一趟兩兩比較後沒有發生任何交換,說明什麼?
[1, 2, 4, 5, 8]
本版本問題:沒有考慮提前結束的情況,導致比較次數爲 10 次
本Python冒泡排序算法版本,交換次數 0
# nums = [5, 1, 4, 2, 8]
# nums = [1,2,3,4,5,6,7,8,9] # 冒泡排序算法優化demo1:
                    #如果兩兩從無交換,說明已經可以大團結
nums = [9,8,1,2,3,4,5,6,7]
flag = False
count= 0
swap_count =0
for i in range(len(nums)-1):   
    
    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1
            flag = True
        
    if not flag:  # 如果兩兩從無交換,說明已經可以大團結,的自然表達
        break

            
print(nums)
print("本版本問題:人工可以看到只需要比較21次就夠了,但是實際比較了:",count,"次")
print("本Python冒泡排序算法版本,交換次數",swap_count)

[1, 2, 3, 4, 5, 6, 7, 8, 9]
本版本問題:人工可以看到只需要比較21次就夠了,但是實際比較了: 36 次
本Python冒泡排序算法版本,交換次數 0

上面代碼合適嗎?假設的是每一趟,只要有一趟沒有發生交換,就可以認爲已經是目標順序了。要把標記放在 i 循環裏。

Python冒泡排序算法v1.2

# nums = [5, 1, 4, 2, 8]
# nums = [1,2,3,4,5,6,7,8,9] #  
                    # 
nums = [9,8,1,2,3,4,5,6,7]  # flag修正 demo
# flag = False  # 修正,flag在外面會導致變爲True之後,無法下次外循環中重置爲False
count= 0
swap_count =0
for i in range(len(nums)-1):   
    flag = False # 修正到這裏
    
    for j in range(len(nums) -1 -i):
        count+=1

        if nums[j] > nums[j+1]:
            nums[j],nums[j+1] = nums[j+1],nums[j]
            s_c +=1
            flag = True
        
    if not flag:  #  
        break

            
print(nums)
print("比較次數",count)
print("本Python冒泡排序算法版本,交換次數",swap_count)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
比較次數 21
本Python冒泡排序算法版本,交換次數 0

Python交換排序算法之冒泡總結:

  • 冒泡法需要數據一趟趟比較
  • 可以設定一個標記判斷此輪是否有數據交換髮生,如果沒有發生交換,可以結束排序,如果發生交換,繼續下一輪排序。
  • 最差的排序情況是,初始順序與目標順序完全相反,遍歷次數1,…,n-1之和n(n-1)/2
  • 最好的排序情況是,初始順序與目標順序完全相同,遍歷次數n-1
  • 時間複雜度O(n2) 。

Python冒泡排序算法變體

# nums = [5, 1, 4, 2, 8]
nums = [2,1,3,4,5,6,7,8,9] # 冒泡排序算法優化demo1:
                           #如果兩兩從無交換,說明已經可以大團結
flag = 1 
count = 0
swap_count = 0
for i in range(len(nums)-1):
    if flag == 0:
        break
    else:
        
        for j in range(len(nums) -1 -i):
            count+=1

            if nums[j] > nums[j+1]:
                nums[j],nums[j+1] = nums[j+1],nums[j]
                s_c +=1
                flag = 1
        
            
print(nums)
print("比較次數",count)
print("本Python冒泡排序算法版本,交換次數",swap_count)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
比較次數 36
本Python冒泡排序算法版本,交換次數 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章