插入排序
插入排序的靈感也許來自于撲克牌, 將n按照大小插入到0~n-1中, 當左邊都排序好了, 整個數組也就排序好了
3 5 1 2 4 7 6 8
3 5 1 2 4 7 6 8
1 3 5 2 4 7 6 8
1 2 3 5 4 7 6 8
1 2 3 4 5 7 6 8
1 2 3 4 5 7 6 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
def insertion_sort(array)
return n if array.size == 1
array.each_with_index do |n,i|
j = i-1
while array[j] > n && j >= 0
tmp = array[j]
array[j] = n
array[j+1] = tmp
j -= 1
end
end
array
end
雖然插入排序的的最差時間是O(n^2), 但是對于已經排序好的數組來說, 排序時間只有O(n)
快速排序
快速排序是最簡單, 效率最好的通用排序算法之一
快速排序利用了分治法的思想, 取出數組的第一個值, 作為pviot
比pviot小的值放在左邊, 大的放在右邊
層層遞歸之后, 數組就排序完成
def quick_sort(array)
return array if array.size <= 1
array.shuffle
left, right = array[1..-1].partition {|n| n <= array.first}
quick_sort(left) + [array.first] + quick_sort(right)
end
快排的復雜度只有O(n*ln(n)), 與插入排序相比, 速度提高了一個級別
對于已經排序好的數組來說, pviot的取值會導致, 左邊的數組的值遠遠多余右邊的數組, 這樣會大大降低快排的效率
所以 在排序前打亂數組對快排來說反而是有益的
使用一下代碼對插入排序和快速排序測試,
a = Array.new
10000.times {a << rand(999)}
b = a.clone
o = Time.now
insertion_sort a
puts Time.now-o
p = Time.now
quick_sort b
puts Time.now-p
insertion_sort: 2.610087
quick_sort: 0.2639
可以看到兩個算法在對大數組排序時的性能差距