-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathradix_sort.rb
More file actions
123 lines (115 loc) · 3.75 KB
/
Copy pathradix_sort.rb
File metadata and controls
123 lines (115 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
require_relative '../GettingStarted/bubble_sort'
module SortingInLinearTime
class << self
# Public: Sorts data with integer keys by grouping keys by the individual
# digits which share the same significant position and value.
#
# NOTE: USING STABLE SORT (BUBBLE SORT)
#
# ARGS:
# a - Input array
# d - Highest order digit
#
# RETURN: Sorted array
#
# COMPLEXITY: Θ(w*n)
#
# Examples
# radix_sort([329, 457, 657, 839, 436, 720, 355], 3)
# => [329, 355, 436, 457, 657, 720, 839]
def radix_sort(arr, d)
stable_sortable_array = arr.map { |x| [x, 0] }
(0..d-1).reverse_each do |digit|
stable_sortable_array = number_ndigit_pair(stable_sortable_array.map { |x| x[0]}, d - 1 - digit)
GettingStarted::bubble_sort_for_radix_sort(stable_sortable_array)
end
stable_sortable_array.map { |x| x[0] }
end
# Public: Builds an array of arrays with first index as the number and
# second index as the digit at specified location from the number
#
# ARGS:
# arr - Input array
# digit_offset - Specific digit position (like 10's or 100's)
#
# RETURN: Sorted array
#
# Examples
# number_ndigit_pair([329, 457, 657, 839, 436, 720, 355], 0)
# => [[329, 9], [355, 5], [436, 6], [457, 7], [657, 7], [720, 0], [839, 9]]
# 0 is the units digit, 1 is the 10's digit and 2 is the 100's digit and so on
def number_ndigit_pair(array, digit_offset)
pair_array = []
array.each do |number|
pair_array << [number, (number / 10 ** (digit_offset) % 10)]
end
pair_array
end
# Public: Sorts data with integer keys by grouping keys by the individual
# digits which share the same significant position and value.
#
# NOTE: USING UNSTABLE SORT (QUICK SORT)
#
# ARGS:
# a - Input array
# d - Highest order digit
#
# RETURN: Sorted array
#
# Examples
# radix_sort_unstable([329, 457, 657, 839, 436, 720, 355], 3)
# => [329, 355, 436, 457, 657, 720, 839]
def radix_sort_unstable(arr, d)
arrayified_hash = prepare_number_to_digit_array_map(arr, d).to_a
(0..d-1).reverse_each do |digit|
arrayified_hash.sort! { |x, y| x[1][digit] == y[1][digit] ?
x[0] <=> y[0] :
x[1][digit] <=> y[1][digit]
}
end
arrayified_hash.map { |x| x[0] }
end
# Public: Builds an hash of arrays where first index is the number and
# second index is an array with digits in each element
#
# ARGS:
# a - Input array
# d - Highest order digit
#
# Examples
# prepare_number_to_digit_array_map([329, 457, 657, 839, 436, 720, 355], 3)
# => [
# [329, [3, 2, 9]], [355, [3, 5, 5]], [436, [4, 3, 6]],
# [457, [4, 5, 7]], [657, [6, 5, 7]], [720, [7, 2, 0]],
# [839, [8, 3, 9]]
# ]
def prepare_number_to_digit_array_map(arr, d)
hash = {}
arr.each do |number|
hash[number] = number_to_digit_array(number, d)
end
hash
end
# Public: Builds an array with first index as the number and second index as
# the array with elements
#
# ARGS:
# number - Number to be augmented
# max_size - Length of second index in the result (OPTIONAL)
#
# Examples
# number_to_digit_array(329)
# => [329, [3, 2, 9]]
def number_to_digit_array(number, max_size=0)
array = []
while number != 0
array << number % 10
number /= 10
end
(0..((max_size)-(array.length)-1)).each do |x|
array << 0
end
array.reverse
end
end
end