基礎演算法之排序
阿新 • • 發佈:2021-07-16
前言:
冒泡,選擇:使用了普通雙指標法
插入,快速,歸併:使用了二分法,遞迴
氣泡排序
原理:不斷比較相鄰兩個數得大小,把較大的數交換到靠後的位置
def bubbleSort(iList): '''氣泡排序 ''' if len(iList) <= 1: return iList for i in range(1, len(iList)): for j in range(0, len(iList)-i): # 原理:不斷比較相鄰兩個數得大小,把較大的數交換到靠後的位置 if iList[j] >= iList[j+1]: #比較相鄰兩數的大小 iList[j], iList[j+1] = iList[j+1], iList[j] #將大數交換到靠後的位置 # print("第 %d 輪排序結果:" %i, end="") # print(iList) return iList
選擇排序
原理
# 藉助了min函式和列表切片
# 不斷從列表中選出最大或者最小的數,放到合適的位置
# 然後再丟擲這個數的子數列中找最大(最小)的數,並放到合適的位置(採用覆蓋列表值<==這個經常再排序中用到)
# 直到子數列為空
程式碼
def selectionSort(iList): if len(iList) <= 1: return iList for i in range(0, len(iList)-1): # 藉助了min函式和列表切片 # 不斷從列表中選出最大或者最小的數,放到合適的位置 # 然後再丟擲這個數的子數列中找最大(最小)的數,並放到合適的位置(採用覆蓋列表值<==這個經常再排序中用到) # 直到子數列為空 if iList[i] != min(iList[i:]): #使用min函式找到剩餘數列中最小的那個數 minIndex = iList.index(min(iList[i:])) #minIndex是最小數的序號(下標) iList[i], iList[minIndex] = iList[minIndex], iList[i] # print("第 %d 輪排序結果:" %(i+1), end="") # print(iList) return iList
插入排序
# 原理:將數列分成兩部分,第一個時left部分,其餘的數為right部分
# 將right部分逐一取出,插入left部分中合適的位置
# 當left部分為空時,left部分就成了一個有序數列
程式碼
def insertionSort(iList): if len(iList) <= 1: return iList for right in range(1, len(iList)): # 原理:將數列分成兩部分,第一個時left部分,其餘的數為right部分 # 將right部分逐一取出,插入left部分中合適的位置 # 當left部分為空時,left部分就成了一個有序數列 target = iList[right] for left in range(0, right): if target <= iList[left]: # 下面這句為什麼往後移一位沒弄懂 iList[left+1:right+1] = iList[left:right] # 比target大的left部分整體後移一位 iList[left] = target # 使用Python的切片賦值 break # print("第 %d 輪排序結果:" %(right), end="") # print(iList) return iList
歸併排序
原理
原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
# 在合併到一起就完成了一個有序序列
程式碼
def mergeSort(iList):
# 原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
# 在合併到一起就完成了一個有序序列
if len(iList) <= 1:
return iList
# 列表指數為基數時拆分列表
middle = len(iList)//2
left, right = iList[0:middle], iList[middle:]
return mergeList(mergeSort(left), mergeSort(right))
def mergeList(left, right):
mList = []
while left and right:
if left[0] >= right[0]:
mList.append(right.pop(0))
else:
mList.append(left.pop(0))
# 下面沒搞懂 刪除的話 就是錯誤排序
# 下面的left,right為真,取出該數列中的第一個元素
while left:
mList.append(left.pop(0))
while right:
mList.append(right.pop(0))
return mList
快速排序
原理
原理:以列表中的任意一個數為基準,將列表分成左右兩個字列表
# 左列表的數要比基數小
# 右列表的數要比基數大
# 然後繼續把左子列表,右子列表按同樣的方式分解,比較,直到分無可分為止
# 一般的話基數為索引第一個
程式碼
def quickSort(iList):
if len(iList) <= 1:
return iList
left = []
right = []
for i in iList[1:]: # 這裡不設定0的話,iList的要為多少呢[],難道說只要比基準數大1;不設定0的話,設定1就會比0少一半得出的資料;
# 原理:以列表中的任意一個數為基準,將列表分成左右兩個字列表
# 左列表的數要比基數小
# 右列表的數要比基數大
# 然後繼續把左子列表,右子列表按同樣的方式分解,比較,直到分無可分為止
# 一般的話基數為索引第一個
if i <= iList[0]:
left.append(i)
else:
right.append(i)
return quickSort(left) + [iList[0]] + quickSort(right) # 這裡遞迴
計數排序
原理
原理:在一個相同的索引i下,求出有多少個數比i小,然後再把該i索引的值寫入多少個數對應的索引值
程式碼
def countingSort(iList):
if len(iList) <= 1:
return iList
iLen = len(iList)
rList = [None]*iLen
for i in range(iLen): # 好經典
small = 0 #比基數小的
same = 0 #與基數相等的
for j in range(iLen):
if iList[j] < iList[i]: # 這個是判斷出有多少個數比身為i索引時小
small += 1 # 但這個數字加不會越來越多麼,在一個迴圈中
elif iList[j] == iList[i]: #相同的數
same += 1
for k in range(small, small+same): # 這個就是怎麼把對應的數插在對應索引下麼
# 原理:在一個相同的索引i下,求出有多少個數比i小,然後再把該i索引的值寫入多少個數對應的索引值
rList[k] = iList[i] # 這個i有點狠,還在i的迴圈裡
return rList
沒搞懂的地方:
插入排序
iList[left+1:right+1] = iList[left:right] # 比target大的left部分整體後移一位
歸併排序
# 下面沒搞懂 刪除的話 就是錯誤排序
# 下面的left,right為真,取出該數列中的第一個元素
while left:
mList.append(left.pop(0))
while right:
mList.append(right.pop(0))
return mList
知識點:
# 列表指數為奇數時拆分列表
middle = len(iList)//2
left, right = iList[0:middle], iList[middle:]
# 建立雙指標
for i in range(1, len(iList)):
for j in range(0, len(iList)-i):
# 遞迴呼叫本身函式
def mergeSort(iList):
# 原理:無限的的把左右序列變成兩個子數列,然後將左右兩個子數列排序完畢後(這裡的子數列分成了1個單位)
# 在合併到一起就完成了一個有序序列
if len(iList) <= 1:
return iList
# 列表指數為奇數時拆分列表
middle = len(iList)//2
left, right = iList[0:middle], iList[middle:]
return mergeList(mergeSort(left), mergeSort(right))
努力拼搏吧,不要害怕,不要去規劃,不要迷茫。但你一定要在路上一直的走下去,儘管可能停滯不前,但也要走。