1. 程式人生 > >經典排序算法及python實現

經典排序算法及python實現

設計 python get 排序。 技術 排好序 sort RR 第一部分

今天我們來談談幾種經典排序算法,然後用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

插入排序

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

技術分享圖片

技術分享圖片

算法實現:

‘‘‘
插入排序
‘‘‘
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

經典排序算法及python實現