1. 程式人生 > >資料結構與演算法之氣泡排序

資料結構與演算法之氣泡排序

一、前言

氣泡排序是一種交換排序。

什麼是交換排序呢?答曰:交換排序即兩兩比較待排序的關鍵字,並交換不滿足次序要求的那對數,直到整個表都滿足次序要求為止。

二、演算法思想

它重複地走訪要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。

這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端,故名氣泡排序

三、程式碼

# -*- 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