1. 程式人生 > >python 冒泡排序,插入排序,歸並排序,快速排序實現code

python 冒泡排序,插入排序,歸並排序,快速排序實現code

classname mes 復雜度 最優 pan ~~ blog merge 復雜

import time
import random

time.clock()

class BubbleSort(object):
    """冒泡排序算法"""
    def sort_inc(self, nums):
        """如果數組長度為n,那麽時間復雜度:
        一共比較n-1次,
        第X次     比較次數
        1           n-1
        2           n-2
        ...
        n-1         1
        時間復雜度為比較次數的和:1 + 2 + 3 + 。。。。 + n-1 = n(n-1)/2
        復雜度去除常數和低階項,結果是O(n^2)
        
""" length = len(nums) if length == 1: return nums for i in range(length-1): for j in range(i+1, length): if nums[i] > nums[j]: nums[i], nums[j] = nums[j], nums[i] return nums class InsertSort(object):
"""插入排序算法""" def sort_inc(self, nums): """如果數組長度為n,那麽時間復雜度: 一共比較n-1次,數組元素從1 -> n-1 第X次 比較次數 1 <=1 2 <=2 ... n-1 <= n-1 時間復雜度為比較次數的和:1 + 2 + 3 + 。。。。 + n-1 = n(n-1)/2 復雜度去除常數和低階項,結果是O(n^2)
""" length = len(nums) if length == 1: return nums for i in range(1, length): key = nums[i] for j in range(i-1, -1, -1): if key < nums[j]: nums[j+1] = nums[j] else: nums[j+1] = key break # 從這裏退出循環是不會執行下面的else的 else: # 不是從break退出的,所以所有的數字都比key大,key應該放在第一個 nums[0] = key return nums class MergeSort(object): """合並排序""" def sort_inc(self, nums): length = len(nums) if length == 1: return nums sorted_num1 = self.sort_inc(nums[:length >> 1]) sorted_num2 = self.sort_inc(nums[length >> 1:]) # 將1和2排序 length1 = len(sorted_num1) length2 = len(sorted_num2) l1 = 0 l2 = 0 ret = [] while True: if l1 < length1 and l2 < length2: if sorted_num1[l1] < sorted_num2[l2]: ret.append(sorted_num1[l1]) l1 += 1 else: ret.append(sorted_num2[l2]) l2 += 1 elif l1 == length1: ret += sorted_num2[l2:] break elif l2 == length2: ret += sorted_num1[l1:] break else: print("ERROR: l1 = %d, l2 = %d" % (l1, l2)) exit(-1) return ret class FastSort(object): def sort_inc(self, nums, left, right): if left >= right: return key = nums[left] # 記錄基準值 keng = left # 記錄坑的索引值 i = left j = right # 填坑,退出循環時i = j = keng while i < j: # 從右往左找小值 while i < j: if nums[j] < key: # 找到小值拿去填坑,將坑至於當前位子 nums[keng] = nums[j] keng = j break j -= 1 # # 從左往右找大值 while i < j: if nums[i] > key: nums[keng] = nums[i] keng = i break i += 1 # 坑填完後,把key填到坑裏 nums[keng] = key self.sort_inc(nums, left, keng-1) self.sort_inc(nums, keng+1, right) return nums def test_func(className, *args): test = className() begin = time.clock() ret = test.sort_inc(*args) end = time.clock() cost_time = end - begin print(str(className) + "running time:\t", cost_time) return ret, cost_time mt = 0 ft = 0 it = 0 bt = 0 # 是否測試 isMergeSort, isFastSort, isInsertSort, isBubbleSort = True, True, False, False test_count = 1000 # 測試次數 data_length = 10000 # 生成測試數據個數 for x in range(test_count): # random test data testlist = [] for i in range(data_length): testlist.append(random.randint(1, 1000000)) # 測試數據範圍 # test part ############################################# if isMergeSort: l1, t1 = test_func(MergeSort, testlist.copy()) mt += t1 if isFastSort: l2, t2 = test_func(FastSort, testlist.copy(), 0, len(testlist) - 1) ft += t2 if isInsertSort: l3, t3 = test_func(InsertSort, testlist.copy()) it += t3 if isBubbleSort: l4, t4 = test_func(BubbleSort, testlist.copy()) bt += t4 print("test %d times, data length is %d" % (test_count, data_length)) if isMergeSort: print("MergeSort:\t", t1 / test_count) if isFastSort: print("FastSort:\t", t2 / test_count) if isInsertSort: print("InsertSort:\t", t3 / test_count) if isBubbleSort: print("BubbleSort:\t", t4/test_count)

時間復雜度:

冒泡排序:

  1+2+。。。+n-1 ~ n2/2

插入排序:

  最優:以及排序好的數組:n-1

  最差:逆序數組:和冒泡一樣,1+2+。。。+n-1 ~ n2/2

歸並排序:

  自己些的分析見下面的文章,時間復雜度:nlogn

  https://www.cnblogs.com/gsp1004/p/10825941.html

  多說一句,我最開始以為空間復雜度是nlogn。但實際是n

  我的錯誤理解:按照樹展開,每層有n個元素,一共logn層,但是並不是這樣的,

  正確的順序的:歸並排序的遞歸會先將樹從左子節點一直執行到最底部的葉子節點,所以空間復雜度:n/2 + n/4 + n/8 + ... + 1 ~ n

快速排序:

  快排的時間復雜度到底怎麽算的現在還是木有搞懂,因為最優就變成了類似歸並O(nlogn),最差就變成了類似冒泡O(n2),但是說什麽平均時間復雜度是O(nlogn)。。。這個待研究。

  但是快排是原地排序,不需要開辟新的內存,也就是空間復雜度是0

自己測試的這幾個排序的時間:

  插入和冒泡是一個量級,但是插入快一些。但是數據量大了後,就真的弱爆了。看下面1w數據執行時間對比就知道了。但是數據量小的時候,比如就幾十個(30個以內?),差異不大,貌似用插入會更快一點點~~~

  快排和歸並是一個量級,但是快排要快一些。這一點我很費解,為什麽快排會快一些???有一個坑要研究一下子。。。

100w數據:

<class ‘__main__.MergeSort‘>running time: 6.76003047388366

<class ‘__main__.FastSort‘>running time: 5.620691225466125

10w數據:

<class ‘__main__.MergeSort‘>running time: 0.5305758325035888

<class ‘__main__.FastSort‘>running time: 0.4379082312716691

1w數據:

<class ‘__main__.MergeSort‘>running time: 0.049988164087996834

<class ‘__main__.FastSort‘>running time: 0.032162911379993483

<class ‘__main__.InsertSort‘>running time: 3.9088220416271278

<class ‘__main__.BubbleSort‘>running time: 6.644870537276558

1w數據跑1k次:

test 1000 times, data length is 10000

MergeSort: 3.865276552134844e-05

FastSort: 2.9817472595865978e-05

test 1000 times, data length is 10000

MergeSort: 3.639758325856235e-05

FastSort: 2.8445983728389024e-05

python 冒泡排序,插入排序,歸並排序,快速排序實現code