《大話資料結構》程式碼實現——第九章 排序
阿新 • • 發佈:2019-02-07
排序方法總體分為三類:
方法類別 | 低階 | 高階 |
插入排序 | 直接插入排序 | 希爾排序 |
選擇排序 | 簡單選擇排序 | 堆排序 |
交換排序 | 氣泡排序 | 快速排序 |
歸併排序 | 歸併排序 |
在此對每個排序方法做下總結以及實現:
一、插入類排序
1. 直接插入排序:將一個記錄插入到已經排好序的有序表中
def zhijiecharu(list): if not list: return false for i in range(1, len(list)): tmp = list[i] j = i-1 if tmp < list[j]: while(list[j] > tmp and j >= 0): list[j+1] = list[j] j -= 1 list[j+1] = tmp return list if __name__ == '__main__': array = [49, 38, 65, 97, 76, 13, 27, 49, 55, 4] print(zhijiecharu(array))
2. 希爾排序:為了使整個序列變得基本有序,在直接插入基礎上,增加了Increment這個變數,先跳著進行一次直接插入排序,這個跳的步幅越來越小,最後一次就是1.
寫程式碼時出錯的點:
(1)temp搞不清楚是給新來的數還是下標減increment的數
(2)while裡面經常忘了寫and j>=0這個條件
def shell_sorted(list): if not list: print(False) incremnt = len(list) while incremnt > 1: incremnt = incremnt // 3 + 1 # print(incremnt) for i in range(incremnt, len(list)): temp = list[i] j = i - incremnt if list[j] > temp: while(list[j] > temp and j >= 0): list[j+incremnt] = list[j] j -= incremnt list[j+incremnt] = temp return list if __name__ == '__main__': array = [49, 38, 65, 97, 76, 13, 27, 49, 55, 4] print(shell_sorted(array))
二、選擇排序類
1. 簡單選擇排序:在當前下標以後,選擇最小的數,和當前下標的數作比較並且交換
def easy_select(list): if not list: return False for i in range(len(list)): min_ind = i min_key = list[i] for j in range(i+1,len(list)): if list[j] < min_key: min_key = list[j] min_ind = j if i!=min_ind: temp = list[i] list[i] = min_key list[min_ind] = temp return list if __name__ == '__main__': array = [49, 38, 65, 97, 76, 13, 27, 49, 55, 4] print(easy_select(array))
2. 堆排序:先將整個序列排成大頂堆,將堆頂元素與序列最後一個元素互換,再對前n-1個數字排成大頂堆。
寫程式碼時出錯的點:
(1) python中下標不能直接乘以2,應該2*(i+1)-1
(2)while的最後一句有點不太清楚是寫外面還是寫裡面
def swap(list, i, j):
temp = list[i]
list[i] = list[j]
list[j] = temp
return list
def get_heap(list, start_ind, end_ind):
j = 2 * (start_ind + 1) - 1
while(j <= end_ind ):
temp = list[start_ind]
if (j+1)<=end_ind and list[j] < list[j+1]:
j +=1
if list[j] <= temp:
break
else:
list[start_ind] = list[j]
list[j] = temp
start_ind = j
j = 2*(j+1)-1
# list[(j+1)//2-1] = temp
print(list)
def heap_sort(list):
if not list:
return False
for i in range(len(list)//2-1,-1,-1):
m = len(list)-1
get_heap(list, i, m)
for j in range(len(list)-1,-1,-1):
swap(list, 0, j)
get_heap(list, 0, j-1)
return list
if __name__ == '__main__':
array = [49, 38, 65, 97, 76, 13, 27, 49, 55, 4]
array2 = [5,1,9,3,7,4,8,6,2]
# print([i for i in range(3,-1,-1)])
print(heap_sort(array2))
三、交換類排序
1. 氣泡排序:相鄰兩個逐個對比
def maopao(list):
if not list:
return False
for i in range(len(list) - 1):
for j in range(len(list)-2, i-1, -1):
if list[j] > list[j+1]:
temp = list[j]
list[j] = list[j+1]
list[j+1] = temp
return list
if __name__ == '__main__':
array = [9,1,5,8,3,7,4,6,2]
print(maopao(array))
2. 快速排序:首先選定一個pivotkey並獲取其在待排序列中的座標Pivot,保證pivot左邊所有數字均小於pivotkey,右邊所有數字均大;根據pivot位置,將待排序列分成左右兩個子序列,再對兩個子序列進行遞迴來排序。(排序的交換操作實際上在獲取pivot的過程中進行)
def quick_sort(list):
if not list:
return False
qsort(list, 0, len(list)-1)
return list
def get_pivot_ind(list, low, high):
# get pivot
mid = (low + high)//2
if list[low] > list[high]:
temp = list[low]
list[low] = list[high]
list[high] = temp
if list[mid] > list[high]:
temp = list[mid]
list[mid] = list[high]
list[high] = temp
if list[low] < list[mid]:
list[mid],list[low] = list[low],list[mid]
# temp = list[mid]
# list[mid] = list[low]
# list[low] = temp
temp = list[low]
while(low < high):
while(low < high and list[high] > temp):
high -= 1
list[low] = list[high]
while(low < high and list[low] < temp):
low += 1
list[high] = list[low]
list[low] = temp
return low
def qsort(list, low, high):
while (low < high):
pivotind = get_pivot_ind(list, low, high)
qsort(list, low, pivotind-1)
low = pivotind + 1
return list
if __name__ == '__main__':
array = [9,1,5,8,3,7,4,6,2]
print(quick_sort(array))
四、歸併類排序