python寫幾個排序演算法
阿新 • • 發佈:2020-12-09
def maopao(data: list): """ 兩兩比較 :param data: :return: """ length = len(data) for i in range(length - 1): flag = True for j in range(length - 1 - i): if data[j] > data[j + 1]: data[j], data[j + 1] = data[j + 1], data[j] flag = False print(i, data) if flag: break def choice(data: list): """ 對未排序的元素中選出最小值替換到當前位置 :param data: :return: """ length = len(data) for i in range(length - 1): min_index = i for j in range(i + 1, length): if data[j] < data[min_index]: min_index = j data[i], data[min_index] = data[min_index], data[i] print(i, data) def insert(data: list): """ 從第二個元素開始,跟左邊的所有元素比較,找到它比左邊元素小的地方,把它從原位置插入到這個地方 :param data: :return: """ length = len(data) for i in range(1, length): # 找到合適的位置 for j in range(i): if data[i] < data[j]: data.insert(j, data.pop(i)) print(i - 1, data) def quick(data: list): """ 從陣列中選擇一個元素稱之為中軸元素,然後把陣列中所有小於中軸元素的元素放在其左邊, 所有大於或等於中軸元素的元素放在其右邊,顯然,此時中軸元素所處的位置的是固定的,也就是說,我們無需再移動中軸元素的位置。 從中軸元素那裡開始把大的陣列切割成兩個小的陣列(兩個陣列都不包含中軸元素), 接著我們通過遞迴的方式,讓中軸元素左邊的陣列和右邊的陣列也重複同樣的操作, 直到陣列的大小為1,此時每個元素都處於有序的位置。 :param data: :return: """ if not data: return [] length = len(data) tmp = data[0] small = [] big = [] i = 0 times = 0 while times < length: if data[i] < tmp: small.append(data.pop(i)) elif data[i] > tmp: big.append(data.pop(i)) else: i += 1 times += 1 return quick(small) + data + quick(big) def mergesort(seq: list): """ 先把一個序列從中間分開,然後把兩個序列再次分開,直到只有一個元素為止, 然後兩兩排序合併,再四四排序合併,再八八排序合併...最後合併到一起 """ def merge(left, right): result = [] # 新的已排序好的列表 i = 0 # 下標 j = 0 # 對兩個列表中的元素 兩兩對比。 # 將最小的元素,放到result中,並對當前列表下標加1 while i < len(left) and j < len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result += left[i:] result += right[j:] return result if len(seq) <= 1: return seq mid = len(seq) // 2 # 將列表分成更小的兩個列表 # 分別對左右兩個列表進行處理,分別返回兩個排序好的列表 left_list = mergesort(seq[:mid]) right_list = mergesort(seq[mid:]) # 對排序好的兩個列表合併,產生一個新的排序好的列表 return merge(left_list, right_list) def heapsort(seq: list): def make_heap(data: list): """ 把陣列變成一個大頂堆. :param data: :return: """ length = len(data) # 遍歷所有的父結點位置,從後往前遍歷 for parentNode in range(length // 2 - 1, -1, -1): while True: # 當前節點的左子節點 sonNode = parentNode * 2 + 1 if sonNode >= length: break # sonNode+1 是右子節點 # 若右子節點在最後一個節點之前,並且右子節點比左子節點大,把孩子指標移到右子節點上,這樣就可以交換更大的數 if (sonNode + 1 <= length - 1) and (data[sonNode + 1] > data[sonNode]): sonNode += 1 if data[parentNode] < data[sonNode]: data[sonNode], data[parentNode] = data[parentNode], data[sonNode] else: break # 依次取出第0項,然後重建堆 result = [] length = len(seq) for end in range(length): make_heap(seq) result.append(seq.pop(0)) return result if __name__ == '__main__': import random source = [random.randint(0, i) for i in range(5, 999)] # source = [6, 5, 7, 2, 11, 4, 10, 2, 5, 3, 1, 9, 6, 4] print('-', source) # maopao(source) # choice(source) # insert(source) # print(mergesort(source)) sorts = source.copy() sorts.sort(reverse=True) aa = heapsort(source) print(sorts == aa)