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)
時間複雜度:html
冒泡排序:算法
1+2+。。。+n-1 ~ n2/2數組
插入排序:app
最優:以及排序好的數組:n-1dom
最差:逆序數組:和冒泡同樣,1+2+。。。+n-1 ~ n2/2測試
歸併排序:spa
本身些的分析見下面的文章,時間複雜度:nlogncode
https://www.cnblogs.com/gsp1004/p/10825941.htmlhtm
多說一句,我最開始覺得空間複雜度是nlogn。但實際是nblog
個人錯誤理解:按照樹展開,每層有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