資料結構與演算法之氣泡排序
一、前言
氣泡排序是一種交換排序。
什麼是交換排序呢?答曰:交換排序即兩兩比較待排序的關鍵字,並交換不滿足次序要求的那對數,直到整個表都滿足次序要求為止。
二、演算法思想
它重複地走訪要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。
這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端,故名氣泡排序
三、程式碼
# -*- coding: utf-8 -*- """ Created on Sat Mar 24 09:56:56 2018 @author: su """ def bubblesort(input_list): if(len(input_list)==0): return [] sort_list=input_list for i in range(len(sort_list)-1): print("第{}次排序".format(i+1)) for j in range(len(sort_list)-1): if(sort_list[j+1]<sort_list[j]): sort_list[j+1],sort_list[j]=sort_list[j],sort_list[j+1] print(sort_list) return sort_list if __name__=='__main__': input_list=[25,65,2,36,0,256] print('排序前:',input_list) sort_list=bubblesort(input_list) print('排序後:',sort_list)
執行結果:
四、演算法分析
1.氣泡排序演算法的效能
2.時間複雜度
若檔案的初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M均達到最小值:Cmin = N - 1, Mmin = 0。所以,氣泡排序最好時間複雜度為O(N)。
但是上述程式碼,不能掃描一趟就完成排序,它會進行全掃描。所以一個改進的方法就是,當冒泡中途發現已經為正序了,便無需繼續比對下去。改進方法一會兒介紹。
若初始檔案是反序的,需要進行 N -1 趟排序。每趟排序要進行 N - i 次關鍵字的比較(1 ≤ i ≤ N - 1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值:
Cmax = N(N-1)/2 = O(N^2)
Mmax = 3N(N-1)/2 = O(N^2)
氣泡排序的最壞時間複雜度為O(N^2)。
因此,氣泡排序的平均時間複雜度為O(N^2)。
總結起來,其實就是一句話:當資料越接近正序時,氣泡排序效能越好。
3.演算法穩定性
氣泡排序就是把小的元素往前調或者把大的元素往後調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。
所以相同元素的前後順序並沒有改變,所以氣泡排序是一種穩定排序演算法。
五、優化
對氣泡排序常見的改進方法是加入標誌性變數exchange,用於標誌某一趟排序過程中是否有資料交換。
如果進行某一趟排序時並沒有進行資料交換,則說明所有資料已經有序
程式碼:
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 24 10:51:32 2018
@author: su
"""
def bubblesort(input_list):
if(len(input_list)==0):
return []
sort_list=input_list
for i in range(len(sort_list)-1):
bChange=False
print("第{}次排序".format(i+1))
for j in range(len(sort_list)-1):
if(sort_list[j+1]<sort_list[j]):
sort_list[j+1],sort_list[j]=sort_list[j],sort_list[j+1]
bChange=True
print(sort_list)
if not bChange:
break
return sort_list
if __name__=='__main__':
input_list=[0,65,2,36,25,256]
print('排序前:',input_list)
sort_list=bubblesort(input_list)
print('排序後:',sort_list)
執行結果:
由執行結果可見,第三次排序已無資料交換,所以就結束排序。
參考:http://cuijiahua.com/blog/2017/12/algorithm_1.html