希爾排序思路:
複習一下插入排序:
def insert_sort(li):再看實現希爾排序**:for i in range(1
, len(li)):
j = i - 1
# j 為手裡最大的牌
tmp =li[i]
while j >= 0 and li[j] >tmp: # 只要手裡最大的牌比摸回來的牌大就一致往右移動
# j >= 0
,說明所有數都比摸到的牌要大,直接退出迴圈
li[j+1] =li[j] # 右移
j -= 1
li[j+1] = tmp # 確定要插入的時候,是必須插到j的前乙個位置
def insert_sort(li, gap):希爾排序小結:for i in
range(gap, len(li)):
j = i -gap
tmp =li[i] # 摸回來的牌的值
while j >= 0 and li[j] >tmp:
# 在有序區裡面,摸回來的牌比有序區的牌(從右到左)的值小,有序區的牌就向右移動乙個位置
li[j+gap] =li[j]
j -=gap
li[j+gap] =tmp
def shell_sort(li):
d = len(li) //
2while d >= 1
: insert_sort(li, d)
d = d //
2li = list(range(1000
))import random
random.shuffle(li)
shell_sort(li)
print(li)
希爾排序的時間複雜度比較複雜,且和選區的grap序列有關。
現在有乙個列表,已知列表中的數範圍都在0到100之間。設計演算法在o(n)時間複雜度內將列表進行排序。
思路:建立乙個列表,用來統計每個數出現的次數。(index存數字大小,value存出現次數)
def count_sort(li, max_num):計數排序的缺點:# 建立乙個max_num長的列表
count = [0
for i in range(max_num + 1
)]
for num in
li: count[num] += 1
li.clear()
for ind, val in
enumerate(count):
for i in
range(val):
import random
li = [random.randint(0,100) for _ in range(1000
)]count_sort(li, len(li))
print(li)
如果列表只有5個數,數字範圍是1到1億,就需要開乙個一億長度的列表,嚴重浪費空間和資源不合理使用。
在計數排序中,如果元素的範圍比較大(比如在1到1億之間), 如何改造演算法?
桶排序(bucket sort):首先將元素分在不同的桶中,再對每個桶中元素排序。
range(n)] # 建立通
forvar
inli:
i = min(var
//(max_num
//n), n-1) # i表示var放到幾號桶裡
) # 把var加到桶裡
# 保持桶內的順序
for j in range(len(buckets[i])-1, 0, -1
):
if buckets[i][j] < buckets[i][j-1]: # 必須是公升序 降序的話[9,8,7,6] [99,87,55,22
], 合併之後並不是有序
buckets[i][j], buckets[i][j-1] = buckets[i][j-1
], buckets[i][j]
else
:
break
sorted_li =
for buc in
buckets:
sorted_li.extend(buc)
return
sorted_li
import random
li = [random.randint(0,99999) for i in range(100
)]li =bucket_sort(li)
print(li)
基數排序是按照低位先排序,然後收集;再按照高位排序,然後再收集;依次類推,直到最高位。
max_num = max(li) # 最大值 9->1, 99->2, 888->3, 10000->5
it = 0
while
10 ** it <=max_num:
buckets = [ for _ in range(10
)]
forvar
inli:
# 987 it=1
987//
10->98 98%10->8; it=2 987
//100->9 9%10=9
digit = (var
//10 ** it) % 10
) # 分桶完成
li.clear()
for buc in
buckets:
li.extend(buc)
# 把數重新寫回li
it += 1
桶排序 基數排序 計數排序
桶排序 1.原理 將需要排序的陣列分在有限的桶裡 然後對每個桶中的數分別排序 對每個桶的操作 1.別的排序演算法 2.以遞迴的方式繼續使用桶排序 2.過程 假設待排序的一組數統一的分布在乙個範圍中,並將這一範圍劃分成幾個子範圍,也就是桶 將待排序的一組數,分檔規入這些子桶,並將桶中的資料進行排序 將...
排序 基數排序(計數排序 桶排序)
在此對於桶排序做出兩種方法 一.簡化版桶排序 如下 簡化版的桶排序 include int main scanf d n 輸入乙個數n,表示接下來有n個數 for i 1 i n i 迴圈讀入n個數,並進行桶排序 for i 0 i 1000 i 依次判斷編號1000 0的桶 getchar get...
桶排序 基數排序 計數基數排序 Java
前面已經講述了很多排序演算法,但是他們的排序演算法都是基於兩個值之間的比較,通過決策樹的方法可以證明深度為d的二叉樹則最多有 一些好的排序演算法是可以達到時間複雜度是線性的,桶排序就是其中一種。比如有n個數,但是這些數的最大數不超過m。這個時候就可以定義乙個含有m個元素的陣列 初始值為0 然後遍歷n...