
Python八大常見排序算法定義、實現(xiàn)及時間消耗效率分析
本文實例講述了Python八大常見排序算法定義、實現(xiàn)及時間消耗效率分析。分享給大家供大家參考,具體如下:
昨晚上開始總結(jié)了一下常見的幾種排序算法,由于之前我已經(jīng)寫了好幾篇排序的算法的相關(guān)博文了現(xiàn)在總結(jié)一下的話可以說是很方便的,這里的目的是為了更加完整詳盡的總結(jié)一下這些排序算法,為了復(fù)習(xí)基礎(chǔ)的東西,從冒泡排序、直接插入排序、選擇排序、歸并排序、希爾排序、桶排序、堆排序??焖倥判蛉胧謥矸治龊蛯崿F(xiàn),在最后也給出來了簡單的時間統(tǒng)計,重在原理、算法基礎(chǔ),其他的次之,這些東西的熟練掌握不算是對之后的工作或者接下來的準(zhǔn)備面試都是很有幫助的,算法重在理解內(nèi)在含義和理論基礎(chǔ),在實現(xiàn)的時候才能避開陷阱少出錯誤,這不是說練習(xí)的時候有錯誤不好而是說,有些不該出現(xiàn)的錯誤盡量還是少出現(xiàn)的好,畢竟好的編程習(xí)慣是離不開嚴(yán)格的約束的,好了,這里就不多說了,復(fù)習(xí)一下基礎(chǔ)知識,共同學(xué)習(xí)吧,下面是具體實現(xiàn),注釋應(yīng)該都很詳細(xì),就不解釋了:
#!usr/bin/env python
#encoding:utf-8
'''''
__Author__:沂水寒城
功能:八大排序算法
'''
import time
import random
time_dict={}
def time_deco(sort_func):
'''''
時間計算的裝飾器函數(shù),可用于計算函數(shù)執(zhí)行時間
'''
def wrapper(num_list):
start_time=time.time()
res=sort_func(num_list)
end_time=time.time()
time_dict[str(sort_func)]=(end_time-start_time)*1000
print '耗時為:',(end_time-start_time)*1000
print '結(jié)果為:', res
return wrapper
def random_nums_generator(max_value=1000, total_nums=20):
'''''
隨機(jī)數(shù)列表生成器
一些常用函數(shù):
random隨機(jī)數(shù)生成
random.random()用于生成一個0到1之間的隨機(jī)數(shù):0 <= n < 1.0;
random.uniform(a, b),用于生成一個指定范圍內(nèi)的隨機(jī)符點數(shù),兩個參數(shù)其中一個是上限,一個是下限。min(a,b) <= n <= max(a,b);
randdom.randint(a, b), 用于生成一個指定范圍內(nèi)的整數(shù),其中a是下限,b是上限: a<= n <= b;
random.randrange(start, stop, step), 從指定范圍內(nèi),按指定基數(shù)遞增的集合獲取一個隨機(jī)數(shù);
random.choice(sequence), 從序列中獲取一個隨機(jī)元素;
random.shuffle(x), 用于將一個列表中的元素打亂;
random.sample(sequence, k), 從指定序列中隨機(jī)獲取指定長度的片斷;
'''
num_list=[]
for i in range(total_nums):
num_list.append(random.randint(0,max_value))
return num_list
#@time_deco
def Bubble_sort(num_list):
'''''
冒泡排序,時間復(fù)雜度O(n^2),空間復(fù)雜度O(1),是穩(wěn)定排序
'''
for i in range(len(num_list)):
for j in range(i,len(num_list)):
if num_list[i]>num_list[j]: #這里是升序排序
num_list[i], num_list[j]=num_list[j], num_list[i]
return num_list
#@time_deco
def Insert_sort(num_list):
'''''
直接插入排序,時間復(fù)雜度O(n^2),空間復(fù)雜度O(1),是穩(wěn)定排序
'''
for i in range(len(num_list)):
for j in range(0,i):
if num_list[i]<num_list[j]: #這里是升序排序,跟冒泡排序差別在于,冒泡是向后遍歷,這個是向前遍歷
num_list[i], num_list[j]=num_list[j], num_list[i]
return num_list
#@time_deco
def Select_sort(num_list):
'''''
選擇排序,時間復(fù)雜度O(n^2),空間復(fù)雜度O(1),不是穩(wěn)定排序
'''
for i in range(len(num_list)):
min_value_index=i
for j in range(i, len(num_list)):
if num_list[j]<num_list[min_value_index]:
min_value_index=j #乍一看,感覺冒泡,選擇,插入都很像,選擇跟冒泡的區(qū)別在于:冒泡是發(fā)現(xiàn)大
#小數(shù)目順序不對就交換,而選擇排序是一輪遍歷結(jié)束后選出最小值才交換,效率更高
num_list[i], num_list[min_value_index]=num_list[min_value_index], num_list[i]
return num_list
#@time_deco
def Merge_sort(num_list):
'''''
歸并排序,時間復(fù)雜度O(nlog?n),空間復(fù)雜度:O(1),是穩(wěn)定排序
'''
if len(num_list)==1:
return num_list
length=len(num_list)/2
list1=num_list[:length]
list2=num_list[length:]
result_list=[]
while len(list1) and len(list2):
if list1[0]<=list2[0]:
result_list.append(list1[0])
del list1[0] #這里需要刪除列表中已經(jīng)被加入到加過列表中的元素,否則最后比較完后列表
else: #中剩余元素?zé)o法添加
result_list.append(list2[0])
del list1[0]
if len(list1): #遍歷比較完畢后列表中剩余元素的添加
result_list+=list1
else:
result_list+=list2
return result_list
#@time_deco
def Shell_sort(num_list):
'''''
希爾排序,時間復(fù)雜度:O(n),空間復(fù)雜度:O(n^2),不是穩(wěn)定排序算法
'''
new_list = []
for one_num in num_list:
new_list.append(one_num)
count=len(new_list)
step=count/2;
while step>0:
i=0
while i<count:
j=i+step
while j<count:
t=new_list.pop(j)
k=j-step
while k>=0:
if t>=new_list[k]:
new_list.insert(k+1, t)
break
k=k-step
if k<0:
new_list.insert(0, t)
#print '---------本輪結(jié)果為:--------'
#print new_list
j=j+step
#print j
i=i+1
#print i
step=step/2 #希爾排序是一個更新步長的算法
return new_list
#@time_deco
def Tong_sort(num_list):
'''''
桶排序,時間復(fù)雜度O(1),空間復(fù)雜度與最大數(shù)字有關(guān),可以認(rèn)為是O(n),典型的空間換時間的做法
'''
original_list = []
total_num=max(num_list) #獲取桶的個數(shù)
for i in range(total_num+1): #要注意這里需要的數(shù)組元素個數(shù)總數(shù)比total_num數(shù)多一個因為下標(biāo)從0開始
original_list.append(0)
for num in num_list:
original_list[num] += 1
result_list = []
for j in range(len(original_list)):
if original_list[j] != 0:
for h in range(0,original_list[j]):
result_list.append(j)
return result_list
def Quick_sort(num_list):
'''''
快速排序,時間復(fù)雜度:O(nlog?n),空間復(fù)雜度:O(nlog?n),不是穩(wěn)定排序
'''
if len(num_list)<2:
return num_list
left_list = [] #存放比基準(zhǔn)結(jié)點小的元素
right_list = [] #存放比基準(zhǔn)元素大的元素
base_node = num_list.pop(0) #在這里采用pop()方法的原因就是需要移除這個基準(zhǔn)結(jié)點,并且賦值給base_node這個變量
#在這里不能使用del()方法,因為刪除之后無法再賦值給其他變量使用,導(dǎo)致最終數(shù)據(jù)缺失
#快排每輪可以確定一個元素的位置,之后遞歸地對兩邊的元素進(jìn)行排序
for one_num in num_list:
if one_num < base_node:
left_list.append(one_num)
else:
right_list.append(one_num)
return Quick_sort(left_list) + [base_node] + Quick_sort(right_list)
def Heap_adjust(num_list, i, size):
left_child = 2*i+1
right_child = 2*i+2
max_temp = i
#print left_child, right_child, max_temp
if left_child<size and num_list[left_child]>num_list[max_temp]:
max_temp = left_child
if right_child<size and num_list[right_child]>num_list[max_temp]:
max_temp = right_child
if max_temp != i:
num_list[i], num_list[max_temp] = num_list[max_temp], num_list[i]
Heap_adjust(num_list, max_temp, size) #避免調(diào)整之后以max為父節(jié)點的子樹不是堆
def Create_heap(num_list, size):
a = size/2-1
for i in range(a, -1, -1):
#print '**********', i
Heap_adjust(num_list, i, size)
#@time_deco
def Heap_sort(num_list):
'''''
堆排序,時間復(fù)雜度:O(nlog?n),空間復(fù)雜度:O(1),不是穩(wěn)定排序
'''
size=len(num_list)
Create_heap(num_list, size)
i = size-1
while i > 0:
num_list[0], num_list[i] = num_list[i], num_list[0]
size -= 1
i -= 1
Heap_adjust(num_list, 0, size)
return num_list
if __name__ == '__main__':
num_list=random_nums_generator(max_value=100, total_nums=50)
print 'Bubble_sort', Bubble_sort(num_list)
print 'Insert_sort', Insert_sort(num_list)
print 'Select_sort', Select_sort(num_list)
print 'Merge_sort', Merge_sort(num_list)
print 'Shell_sort', Shell_sort(num_list)
print 'Tong_sort', Tong_sort(num_list)
print 'Heap_sort', Heap_sort(num_list)
print 'Quick_sort', Quick_sort(num_list)
# print '-----------------------------------------------------------------------------'
# for k,v in time_dict.items():
# print k, v
結(jié)果如下:
Bubble_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Insert_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Select_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Merge_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Shell_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Tong_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Heap_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Quick_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
這里沒有使用到裝飾器,主要自己對這個裝飾器不太了解,在快速排序的時候報錯了,也沒有去解決,這里簡單貼一下一個測試樣例使用裝飾器的結(jié)果吧:
Bubble_sort 耗時為: 0.0290870666504
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Insert_sort 耗時為: 0.0209808349609
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Select_sort 耗時為: 0.0259876251221
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Merge_sort 耗時為: 0.0138282775879
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Shell_sort 耗時為: 0.113964080811
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Tong_sort 耗時為: 0.0460147857666
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Heap_sort 耗時為: 0.046968460083
結(jié)果為: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
None
Quick_sort [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
-----------------------------------------------------------------------------
<function Shell_sort at 0x7f8ab9d34410> 0.113964080811
<function Select_sort at 0x7f8ab9d34230> 0.0259876251221
<function Insert_sort at 0x7f8ab9d34140> 0.0209808349609
<function Heap_sort at 0x7f8ab9d34758> 0.046968460083
<function Merge_sort at 0x7f8ab9d34320> 0.0138282775879
<function Tong_sort at 0x7f8ab9d34500> 0.0460147857666
<function Bubble_sort at 0x7f8ab9d34050> 0.0290870666504
接下來有時間的話我想學(xué)一下裝飾器的東西,感覺對于模式化的東西裝飾器簡直就是一個神器,但是得明白會用會寫才行哈!
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預(yù)測分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢預(yù)判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預(yù)測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點,而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費者需求的重要途徑,而統(tǒng)計學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03