經典排序算法及python實現

今天咱們來談談幾種經典排序算法,而後用python來實現,最後經過數據來比較幾個算法時間python

選擇排序

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到所有待排序的數據元素排完。 選擇排序是不穩定的排序方法(好比序列[5, 5, 3]第一次就將第一個[5]與[3]交換,致使第一個5挪動到第二個5後面)。(注:選自百度百科)算法

假如,有一個無須序列A={6,3,1,9,2,5,8,7,4},選擇排序的過程應該以下:
   第一趟:選擇最小的元素,而後將其放置在數組的第一個位置A[0],將A[0]=6和A[2]=1進行交換,此時A={1,3,6,9,2,5,8,7,4};
   第二趟:因爲A[0]位置上已是最小的元素了,因此此次從A[1]開始,在剩下的序列裏再選擇一個最小的元素將其與A[1]進行交換。即這趟選擇過程找到了最小元素A[4]=2,而後與A[1]=3進行交換,此時A={1,2,6,9,3,5,8,7,4};
   第三趟:因爲A[0]、A[1]已經有序,因此在A[2]~A[8]裏再選擇一個最小元素與A[2]進行交換,而後將這個過程一直循環下去直到A裏全部的元素都排好序爲止。這就是選擇排序的精髓。所以,咱們很容易寫出選擇排序的核心代碼部分,即選擇的過程,就是不斷的比較、交換的過程。
   整個選擇的過程以下圖所示:數組

 

 

 

算法實現:架構

'''
選擇排序
'''
def Selection_sort(a):
    for i in range(len(a) - 1):
        min = i
        for j in range(i + 1, len(a)):
            if a[min] > a[j]:
                min = j
        if min != i:
            a[min], a[i] = a[i], a[min]
    return a

  

冒泡排序

介紹:app

  冒泡排序(Bubble Sort,臺灣譯爲:泡沫排序或氣泡排序)是一種簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,若是他們的順序錯誤就把他們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。這個算法的名字由來是由於越小的元素會經由交換慢慢「浮」到數列的頂端。dom

步驟:函數

  1. 比較相鄰的元素。若是第一個比第二個大,就交換他們兩個。
  2. 對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
  3. 針對全部的元素重複以上的步驟,除了最後一個。
  4. 持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。

 

算法實現oop

'''
冒泡排序
'''
def Dubble_sort(a):
    for i in range(len(a)):
        for j in range(i+1,len(a)):
            if a[i] > a[j]:
                a[i],a[j] = a[j],a[i]
    return a

插入排序

有一個已經有序的數據序列,要求在這個已經排好的數據序列中插入一個數,但要求插入後此數據序列仍然有序,這個時候就要用到一種新的排序方法——插入排序法,插入排序的基本操做就是將一個數據插入到已經排好序的有序數據中,從而獲得一個新的、個數加一的有序數據,算法適用於少許數據的排序,時間複雜度爲O(n^2)。是穩定的排序方法。插入算法把要排序的數組分紅兩部分:第一部分包含了這個數組的全部元素,但將最後一個元素除外(讓數組多一個空間纔有插入的位置),而第二部分就只包含這一個元素(即待插入元素)。在第一部分排序完成後,再將這個最後元素插入到已排好序的第一部分中。  測試

算法實現:ui

'''
插入排序
'''
def Insertion_sort(a):
    for i in range(1,len(a)):
        j = i
        while j>0 and a[j-1]>a[i]:
            j -= 1
        a.insert(j,a[i])
        a.pop(i+1)
    return a

  

快速排序

介紹:

快速排序(Quicksort)是對冒泡排序的一種改進。在平均情況下,排序 n 個項目要Ο(n log n)次比較。在最壞情況下則須要Ο(n2)次比較,但這種情況並不常見。事實上,快速排序一般明顯比其餘Ο(n log n) 算法更快,由於它的內部循環(inner loop)能夠在大部分的架構上頗有效率地被實現出來,且在大部分真實世界的數據,能夠決定設計的選擇,減小所需時間的二次方項之可能性。

步驟:

  1. 從數列中挑出一個元素,稱爲 「基準」(pivot),
  2. 從新排序數列,全部元素比基準值小的擺放在基準前面,全部元素比基準值大的擺在基準的後面(相同的數能夠到任一邊)。在這個分區退出以後,該基準就處於數列的中間位置。這個稱爲分區(partition)操做。
  3. 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

排序效果:

 

算法實現:

'''
快速排序
'''
def sub_sort(array,low,high):
    key = array[low]
    while low < high:
        while low < high and array[high] >= key:
            high -= 1
        while low < high and array[high] < key:
            array[low] = array[high]
            low += 1
            array[high] = array[low]
    array[low] = key
    return low


def quick_sort(array,low,high):
     if low < high:
        key_index = sub_sort(array,low,high)
        quick_sort(array,low,key_index)
        quick_sort(array,key_index+1,high)

  

而後咱們對上面的算法作一個時間比較:

'''''
隨機生成0~10000000之間的數值
'''
def getrandata(num):
    a=[]
    i=0
    while i<num:
        a.append(random.randint(0,10000000))
        i+=1
    return a

'''
隨機生成20個長度爲10000的數組
'''
a = []
for i in range(20):
    a.append(getrandata(10000))

'''
測試時間函數
'''
def time_it(f,a):
    t = []
    for i in range(len(a)):
        t1 = time.time()
        f(a[i])
        t2 = time.time()
        t.append(t2-t1)
    return t
tt1 = time_it(Selection_sort,copy.deepcopy(a))
tt2 = time_it(Dubble_sort,copy.deepcopy(a))
tt3 = time_it(Insertion_sort,copy.deepcopy(a))
tt4 = time_it(Quick_sort,copy.deepcopy(a))
print np.mean(tt1),tt1
print np.mean(tt2),tt2
print np.mean(tt3),tt3
print np.mean(tt4),tt4

  

在我電腦運行結果以下:

3.53101536036 [3.1737868785858154, 3.2235000133514404, 3.296314001083374, 3.3746020793914795, 3.6942098140716553, 3.6844170093536377, 3.3293440341949463, 3.6262528896331787, 3.577023983001709, 3.4677979946136475, 3.5323100090026855, 3.3574531078338623, 3.4525561332702637, 3.4662599563598633, 3.8701679706573486, 3.719839096069336, 3.7798891067504883, 3.6078600883483887, 3.803921937942505, 3.582801103591919]
7.22842954397 [7.1081390380859375, 7.365921974182129, 6.666350841522217, 7.258342027664185, 6.8559088706970215, 6.805047035217285, 7.230466842651367, 7.948682069778442, 7.901662111282349, 7.448035955429077, 8.134574890136719, 7.731559991836548, 7.3559558391571045, 6.80467414855957, 7.227035999298096, 6.987092018127441, 6.9657158851623535, 6.997059106826782, 6.9417431354522705, 6.834623098373413]
2.64084545374 [2.6150870323181152, 2.567375898361206, 2.7965359687805176, 2.616096019744873, 2.561455011367798, 2.76595401763916, 2.603566884994507, 2.542672872543335, 2.783787965774536, 2.643486976623535, 2.5308570861816406, 2.764592170715332, 2.6237199306488037, 2.508751153945923, 2.766709089279175, 2.603114128112793, 2.528198003768921, 2.812356948852539, 2.651564836502075, 2.53102707862854]
0.0346855401993 [0.03456306457519531, 0.0337519645690918, 0.03569507598876953, 0.034551143646240234, 0.03506588935852051, 0.03456687927246094, 0.0352480411529541, 0.03591203689575195, 0.03380298614501953, 0.03402996063232422, 0.034184932708740234, 0.03434491157531738, 0.034864187240600586, 0.035611867904663086, 0.03429007530212402, 0.034512996673583984, 0.03453683853149414, 0.03406691551208496, 0.033792972564697266, 0.036318063735961914]

  

能夠看出,快速排序在隨機生成的數組中速度上十分有優點。

相關文章
相關標籤/搜索