gem algorithms0.1.0 算法部分分析4
今天早上,接着昨天的读,发现我很喜欢这些算法,因为能看懂,而且发现作者使用了许多ruby的特有写法,感觉很好。
def self.shell_sort(container)
increment = container.size/2
while increment > 0 do
(increment..container.size-1).each do |i|
temp = container[i]
j = i
while j >= increment && container[j - increment] > temp do
container[j] = container[j-increment]
j -= increment
end
container[j] = temp
end
increment = (increment == 2 ? 1 : (increment / 2.2).round)
end
container
end
希尔排序,这个才真像了。其中控制增量的很有意思:
increment = container.size/2
开头以表长一半为增量,以后则每次除以2,但如何保证是奇数呢?
increment = (increment == 2 ? 1 : (increment / 2.2).round)
或许我再测试下。
yang@DESKTOP-V9HS3B6:~/test2$ cat qujian.rb
increment=10
while increment>0
puts increment
increment = (increment == 2 ? 1 : (increment / 2.2).round)
end
yang@DESKTOP-V9HS3B6:~/test2$ ruby qujian.rb
10
5
2
1
yang@DESKTOP-V9HS3B6:~/test2$
我的数学不好,反正增量序列为奇数,并且最后一定是1,满足了希尔排序的要求。
接下来是快速排序,快速排序我明白,但作者的写法我不能理解。
def self.partition(data, left, right)
pivot = data[front]
left += 1
while left <= right do
if data[frontUnknown] < pivot
back += 1
data[frontUnknown], data[back] = data[back], data[frontUnknown] # Swap
end
frontUnknown += 1
end
data[front], data[back] = data[back], data[front] # Swap
back
end
我容易理解的是从两头来比较,大的在后,小的在前,再把基准值放中间。这样写,我看不懂。
另外,作者没有用递归,这个也很难懂。
最后是归并排序
def self.mergesort(container)
return container if container.size <= 1
mid = container.size / 2
left = container[0...mid]
right = container[mid...container.size]
merge(mergesort(left), mergesort(right))
end
def self.merge(left, right)
sorted = []
until left.empty? or right.empty?
left.first <= right.first ? sorted << left.shift : sorted << right.shift
end
sorted + left + right
end
看最后一句,把三个数组加起来。很有意思。