解惑連結的一些小問題
阿新 • • 發佈:2020-12-07
排序演算法
標籤(空格分隔): algorithm
氣泡排序
遍歷n趟,每趟把最大的數交換到尾部
def bubble_sort(nums, n): i = n-1 while i > 0: last = 0 for j in range(0, i): if nums[j] > nums[j+1]: nums[j], nums[j+1] = nums[j+1], nums[j] last = j # 如果這一趟沒有發生交換,說明已有序,終止遍歷(last=0) i = last
- 時間複雜度 O(n^2)
- 穩定的排序方法
簡單選擇排序
遍歷n趟,設定(0,n-1)段位有序段,後面為無序段,每趟遍歷從無序段找到最小的數放入有序段尾部
def select_sort(nums, n): i = 0 while i < n: min_index = i for j in range(i+1, n): if nums[min_index] > nums[j]: min_index = j if min_index != i: nums[min_index], nums[i] = nums[i], nums[min_index] i += 1
- 時間複雜度 O(n^2)
- 不穩定的排序方法
對於序列: [48] 36 68 72 12 (48) 02
最終結果: 02 12 36 (48) [48] 68 72
直接插入排序
設定第一個元素為有序序列,然後將剩餘n-1個元素依次插入該序列,每次插入保證該序列有序
def insert_sort(nums, n): i = 1 while i < n: j = i tmp = nums[i] while j > 0 and tmp < nums[j-1]: # 如果tmp < nums[j-1], tmp要插在nums[j-1]前面 # 將nums[j-1]向後移動 nums[j] = nums[j-1] j -= 1 nums[j] = tmp i += 1
- 時間複雜度 O(n^2)
- 穩定的排序演算法
PS: 如果將tmp < nums[j-1]
改成tmp <= nums[j-1]
,就是不穩定的
快速排序
在序列中選取某個元素R,將小於R的元素放在R左側,大於R的放在R右側,然後再分別對R左側和R右側的序列進行快速排序
,直到子序列為空或只有一個元素。
def quick_sort(nums, n):
q_sort(nums, 0, n-1)
def q_sort(nums, left, right):
# nums[left]為元素R
if left < right:
i, j = left, right
while i < j:
while nums[i] < nums[left]:
i += 1
while nums[j] > nums[left]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
# 元素R的最終位置為j
nums[left], nums[j] = nums[j], nums[left]
q_sort(nums, left, j-1)
q_sort(nums, j+1, right)
- 時間複雜度: O(nlogn)
- 不穩定的排序演算法
兩路合併排序
將有n個元素的序列看n個長度為1的有序子序列,然後兩兩合併,得到⌈n/2⌉個長度為2或1的有序子序列;再兩兩合併,……,直到得到長度為n的有序序列時結束。
def merge_sort(nums, n):
# i1, i2是子序列1的下、上界,j1, j2是子序列2的下、上界
i1, i2, j1, j2 = 0, 0, 0, 0
size = 1
while size < n:
i1 = 0
while i1+size < n:
j1 = i1 + size
i2 = j1 - 1
j2 = j1 + size -1
# j2有又可能越界
if j2 > n-1:
j2 = n-1
merge(nums, i1, i2, j1, j2)
i1 = j2+1
size *= 2
def merge(nums, i1, i2, j1, j2):
# i1, i2是子序列1的下、上界,j1, j2是子序列2的下、上界
tmp = []
i, j = i1, j1
while i <= i2 and j <= j2:
if nums[i] < nums[j]:
tmp.append(nums[i])
i += 1
else:
tmp.append(nums[j])
j += 1
while i <= i2:
tmp.append(nums[i])
i += 1
while j <= j2:
tmp.append(nums[j])
j += 1
for i in range(i1, i1+len(tmp)):
nums[i] = tmp[i-i1]
- 時間複雜度:O(nlogn)
- 空間複雜度:O(n)
需要藉助輔助陣列儲存臨時資料- 穩定的排序方法