常用排序演算法總結
阿新 • • 發佈:2020-11-14
實現稍微難點的三個演算法:快排、歸併、堆排序
快速排序
以下是一種寫法(演算法導論上是另一種寫法,待補充)
def quickSort(data, start, end): i = start j = end # i與j重合,一次排序結束 if i >= j: return # 設定最左邊的數為基準值 flag = data[start] while i < j: while i < j and data[j] >= flag: j -= 1 # 找到右邊第一個小於基準的數賦值給左邊i(此時左邊i被記錄在flag中) data[i] = data[j] while i < j and data[i] <= flag: i += 1 # 找到左邊第一個大於基準的數賦值給右邊的j data[j] = data[i] # 迴圈完後把flag值放到i所在位置 data[i] = flag # print(data) # 除去i之外兩段遞迴 quickSort(data, start, i - 1) quickSort(data, i + 1, end) if __name__ == "__main__": data = [6, 5, 8, 2, 3, 1] print(data) quickSort(data, 0, len(data) - 1) print(data)
氣泡排序
def bubbleSort(alist): n = len(alist) exchange = False for i in range(n-1, 0, -1): for j in range(0, i): if alist[j] > alist[j+1]: alist[j], alist[j+1] = alist[j+1], alist[j] exchange = True # 如果發現整個排序過程中沒有交換,提前結束 if not exchange: break return alist
選擇排序
- 選擇排序是在氣泡排序的基礎上優化的,提高了氣泡排序的效能
def selectionSort(alist): n = len(alist) for i in range(n - 1): # 尋找[i,n]區間裡的最小值 min_index = i for j in range(i+1, n): if alist[j] < alist[min_index]: min_index = j alist[i], alist[min_index] = alist[min_index], alist[i] return alist
插入排序
def insertionSort(blist):
n = len(blist)
for i in range(1, n):
# 尋找a[i]合適的插入位置
temp = blist[i]
for j in range(i, 0, -1):
if temp < blist[j-1]:
blist[j] = blist[j-1]
else:
break
blist[j-1] = temp
print(blist)
return blist
希爾排序
- 希爾排序是在插入排序的基礎上優化的,提高了插入排序的效能
def shell1Sort(data):
step = len(data) // 2
while step >= 1:
print("當前增量是:", step)
for i in range(step, len(data)):
for j in range(i-step, -step, -step):
if data[j] > data[j+step]:
data[j], data[j+step] = data[j+step], data[j]
step = int(step/2)
歸併排序
def merge_sort(nums):
if len(nums) <= 1:
return nums
middle = len(nums) // 2
left_num = nums[:middle]
right_num = nums[middle:]
return merge(merge_sort(left_num), merge_sort(right_num))
def merge(left_num, right_num):
len_left = len(left_num)
len_right = len(right_num)
i = j = 0
result = []
# 比較left_num和left_right中的元素,按序新增到result中
while i < len_left and j < len_right:
if left_num[i] > right_num[j]:
result.append(right_num[j])
j += 1
else:
result.append(left_num[i])
i += 1
# 將j中的剩餘元素新增到result中
if i == len_left and j < len_right:
for m in right_num[j:]:
result.append(m)
# 將i中的剩餘元素新增到result中
if j == len_right and i < len_left:
for m in left_num[i:]:
result.append(m)
return result
堆排序(個人感覺演算法很贊)
from collections import deque
# python中交換兩個元素的位置
def swap(nums, i, j):
nums[i], nums[j] = nums[j], nums[i]
return nums
# 構造最大堆
def heap_adjust(nums, start, end):
temp = nums[start]
i = start
j = start * 2
while j <= end:
if j < end and nums[j] < nums[j + 1]:
j += 1
if temp < nums[j]:
nums[i] = nums[j]
i = j
j = i * 2
else:
break
nums[i] = temp
# 堆排序
def heap_sort(nums):
len_heap = len(nums) - 1
len_mid_heap = len_heap // 2
# 將序列調整為一個最大堆
for i in range(len_mid_heap):
heap_adjust(nums, len_mid_heap-i, len_heap)
print(nums)
# 將堆頂元素和堆末尾元素交換,將剩下元素調整為一個最大對
for i in range(len_heap-1):
swap(nums, len_heap-i, 1)
heap_adjust(nums, 1, len_heap-i-1)
print(nums)
return list(nums)[1:]
def main():
L = deque([50, 16, 30, 10, 60, 90, 2, 80, 70])
L.appendleft(0)
print(heap_sort(L))