直接移動 ( 交換資料位置 )
邏輯移動 ( 改變指標,更快 )
jmp = len(data) // 2
while jmp != 0:
# 插入排序
for i in range(jmp, len(data)):
tmp = data[i]
j = i - jmp
while j >= 0 and tmp < data[j]:
data[j + jmp] = data[j]
j -= jmp
data[j + jmp] = tmp
jmp = jmp // 2
合併排序法( merge sort )
針對以排好序的兩個或兩個以上的數列(或資料檔案),通過合併的方式,將其組合成乙個大的且已排好序的數列(或資料檔案)。
2 路( 2-way )合併排序:
① 將 n 個長度為 1 的鍵值,成對的合併成 n/2 個長度為 2 的有序鍵值組
② 將 n/2 個長度為 2 的鍵值組,成對的合併成 n/4 個長度為 4 的有序鍵值組
③ 不斷合併,直到鍵值組長度為 n,且已排好序
l3 =
idx1 = idx2 = 0
for i in range(len(l1) + len(l2)-2):
if l1[idx1] < l2[idx2]:
idx1 += 1
if idx1 == len(l1):
l3.extend(l2[idx2:])
break
else:
idx2 += 1
if idx2 == len(l2):
l3.extend(l1[idx1:])
break
快速排序法( quick sort ) / 分割交換排序法
目前公認最佳。使用了分而治之( divide and conquer )。
先在資料中找到乙個虛擬的中間值,並按此中間值將所有打算排序的資料分為兩部分。小於中間值的再左邊,大於的再右邊。再以同樣的方式分別處理左、右兩邊資料,直到排完序為止。
假設有 n 項記錄 r1,r2,r3,...,rn,其鍵值為 k1, k2,k3,...,kn:
① 先假設 k 的值為第乙個鍵值
② 從左向右找出鍵值 ki,使得 ki > k
③ 從右向左找出鍵值 kj,是的 kj < k
④ 如果 i < j,那麼 ki 與 kj 互換,並回到步驟 ②
⑤ 若 i ≥ j,則將 k 與 kj 互換,並以 j 為基準點分割成左右兩部分。然後針對左右兩部分進行步驟 ① 至 ⑤,直到左半邊鍵值等於右半邊鍵值
def quick(d, size, lf, rg):
# 第一項鍵值為 d[lf]
# size = len(d)
if lf < rg: # 左右兩邊索引值
# ②lf_idx = lf + 1
while d[lf_idx] < d[lf]:
if lf_idx + 1 == size:
break
lf_idx += 1
# ③rg_idx = rg
while d[rg_idx] > d[lf]:
rg_idx -= 1
# ④while lf_idx < rg_idx:
d[lf_idx], d[rg_idx] = d[rg_idx], d[lf_idx]
lf_idx += 1
while d[lf_idx] < d[lf]:
lf_idx += 1
rg_idx -= 1
while d[rg_idx] > d[lf]:
rg_idx -= 1
# ⑤d[lf], d[rg_idx] = d[rg_idx], d[lf]
quick(d, size, lf, rg_idx-1) # 以rg_idx為基準點分成左右兩半,以遞迴方式分別為左右兩邊進行排序直至完成排序
quick(d, size, rg_idx+1, rg)
基數排序法
並不需要元素間進行比較,屬於一種分配模式排序方式。
按比較的方向可分為最高位優先 ( most significant digit first , msd ) 和最低位優先 ( least significant digit first , lsd ) 兩種。
msd 是從最左邊的位數開始比較,lsd 是從最右邊的位數開始比較。
def radix(data):
"""0~999 整數比較"""
n = 1 # n 為基數,從個位開始排序
while n <= 100:
tmp = [[none] * 100 for row in range(10)] # 設定暫存陣列 [[n位為0的所有元素], [?1], [?2], ... , [?9]]。
for i in range(len(data)):
m = (data[i] // n) % 10 # n 位的數值,n=1為個位,n=10為10位
tmp[m][i] = data[i] # 放入棋盤對應位置
k = 0
for i in range(10):
for j in range(len(data)):
if tmp[i][j] is not none:
data[k] = tmp[i][j] # 讀出棋盤裡的值,重構陣列
k += 1
n *= 10
原陣列 [3, 5, 32, 74, 169, 2, 111, 0]過程:比較個位 [0, 111, 32, 2, 3, 74, 5, 169]
比較十位 [0, 2, 3, 5, 111, 32, 169, 74]
比較百位 [0, 2, 3, 5, 32, 74, 111, 169]
結果:[0, 2, 3, 5, 32, 74, 111, 169]
冒泡、選擇、插入排序三種資料搬移量最大的是 插入排序。
合併排序法是穩定的。不會改變兩個相同數字的原有順序。
練習03 排序
a題 big number 題意 求階乘n的結果又多少位數。poj的資料比hdu難過點,但是hdu討論版的斯特林公式可以。我也不會證明,只能抄下來了咯。include include include include include define max 10000005 using namespac...
03 排序 氣泡排序
基本原理 顧名思義就是整個過程向氣泡一樣往上公升,單向氣泡排序的基本原理就是 對於給定的n個資料,從第乙個資料開始一次對相鄰的兩個記錄進行比較,當前面的記錄大於後面的記錄時,交換位置,進行一輪比較和換位後,n個記錄中最大的那個被排在最後,即第n位。然後對前面n 1個記錄進行第二次比較,重複該過程。實...
演算法 排序1 排序
題目 給定n個 長整型範圍內的 整數,要求輸出從小到大排序後的結果。本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下 輸入第一行給出正整數n 10 5 隨後一行給出n個 長整型範圍內的 整數,其間以空格分隔。在一行中輸出從小到大排序後的結果,數字間以1個空格分隔,行末不得...