Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2729615

Browse files
committedFeb 19, 2015
some cheap implementations of mergesort and quicksort
1 parent c18ab9a commit 2729615

File tree

2 files changed

+87
-42
lines changed

2 files changed

+87
-42
lines changed
 

‎week_3/mergesort.rb

+73-39
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,40 @@
11
require 'byebug'
22

33
class MergeSort
4-
# def sort(aux, lo, high)
5-
# return if high <= lo
6-
7-
# mid = lo + (high - lo) / 2
8-
9-
# sort(aux, lo, mid)
10-
# sort(aux, mid + 1, high)
11-
12-
# merge(aux, lo, mid, high)
13-
# end
14-
15-
# def merge(aux, lo, mid, high)
16-
# high.times do |i|
17-
# aux[i] = @actual[i]
18-
# end
19-
20-
# j = mid + 1
21-
# i = lo
22-
23-
# high.times do |k|
24-
# if i > mid
25-
# @actual[k] = aux[j]
26-
# j += 1
27-
# elsif j > high
28-
# # this should only need to find j > high
29-
# @actual[k] = aux[i]
30-
# i += 1
31-
# elsif less(aux[j], aux[i])
32-
# @actual[k] = aux[j]
33-
# j += 1
34-
# else
35-
# @actual[k] = aux[i]
36-
# i += 1
37-
# end
38-
# end
39-
# end
4+
def bottom_up_merge_sort(a)
5+
sz = 1
6+
n = a.count
7+
while sz < n
8+
lo = 0
9+
10+
# Ensure there are at least sz numbers to sort
11+
while lo < (n - sz)
12+
13+
# a[lo..hi] has at most 2*sz numbers or
14+
# at least n-1-lo numbers
15+
hi = [n-1, lo+sz+sz-1].min
16+
17+
# a[lo..mid] has sz numbers
18+
mid = lo+sz-1
19+
20+
merge_it(a, lo, mid, hi)
21+
22+
p a.inspect
23+
24+
lo = hi + 1
25+
end
26+
27+
# Ensure that sz is a power of 2
28+
sz = sz + sz
29+
end
30+
a
31+
end
4032

4133
def merge_sort(array)
4234
return array if array.size <= 1
4335
left = merge_sort array[0, array.size / 2]
4436
right = merge_sort array[array.size / 2, array.size]
4537

46-
# p left, right
4738
merging(left, right)
4839
end
4940

@@ -59,8 +50,51 @@ def merging(left, right)
5950
end
6051
end
6152

62-
something = result.concat(left).concat(right)
63-
p something
53+
result.concat(left).concat(right)
54+
end
55+
56+
def merge_it(a, lo, mid, hi)
57+
# a[lo..mid] and a[mid+1..hi] must be sorted
58+
dup = a.clone
59+
60+
# index for the left sub-array: lo <= i <= mid
61+
i = lo
62+
63+
# index for the right sub-array: mid+1 <= j <= hi
64+
j = mid+1
65+
66+
# index for the sorted sub-array: lo <= k <= hi
67+
k = lo
68+
69+
while k <= hi
70+
# All numbers in left sub-array have been compared
71+
# so copy number from the right sub-array.
72+
if i > mid
73+
a[k] = dup[j]
74+
j += 1
75+
76+
# All numbers in right sub-array have been compared
77+
# so copy number from the left sub-array
78+
elsif j > hi
79+
a[k] = dup[i]
80+
i += 1
81+
82+
# Number in right sub-array is less than the number in
83+
# left sub-array. So copy number from the right sub-array
84+
elsif dup[j] < dup[i]
85+
a[k] = dup[j]
86+
j += 1
87+
88+
# Number in left sub-array is less than the number in
89+
# right sub-array. So copy number from left sub-array
90+
else
91+
a[k] = dup[i]
92+
i += 1
93+
end
94+
k += 1
95+
end
96+
97+
# The array `a[lo..hi]` is sorted.
6498
end
6599

66100
private

‎week_3/mergesort_spec.rb

+14-3
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,25 @@
1515
end
1616
end
1717

18-
describe '#sort' do
18+
xdescribe '#merge_sort' do
1919
context 'given an unsorted array' do
20-
let(:actual) { [42, 28, 65, 49, 24, 43, 94, 33, 79, 57, 86, 56 ] }
20+
let(:actual) { [42, 60, 59, 40, 75, 65, 57, 43, 30, 29, 10, 53] }
2121

2222
it 'returns a sorted array' do
2323
p subject.merge_sort(actual)
2424
# expect(subject.actual).to eq [2,4,5,6,7,8,8,10]
2525
end
26-
end
26+
end
27+
end
28+
29+
describe '#bottom_up' do
30+
context 'given an unsorted array' do
31+
let(:actual) { [17, 11, 68, 79, 36, 13, 33, 35, 99, 91] }
32+
33+
it 'returns a sorted array' do
34+
p subject.bottom_up_merge_sort(actual)
35+
# expect(subject.actual).to eq [2,4,5,6,7,8,8,10]
36+
end
37+
end
2738
end
2839
end

0 commit comments

Comments
 (0)
Please sign in to comment.