-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ruby code - chapter sorting
- Loading branch information
1 parent
d2d4955
commit 06c288d
Showing
4 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
=begin | ||
File: bubble_sort.rb | ||
Created Time: 2024-05-02 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=end | ||
|
||
### 冒泡排序 ### | ||
def bubble_sort(nums) | ||
n = nums.length | ||
# 外循环:未排序区间为 [0, i] | ||
for i in (n - 1).downto(1) | ||
# 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 | ||
for j in 0...i | ||
if nums[j] > nums[j + 1] | ||
# 交换 nums[j] 与 nums[j + 1] | ||
nums[j], nums[j + 1] = nums[j + 1], nums[j] | ||
end | ||
end | ||
end | ||
end | ||
|
||
### 冒泡排序(标志优化)### | ||
def bubble_sort_with_flag(nums) | ||
n = nums.length | ||
# 外循环:未排序区间为 [0, i] | ||
for i in (n - 1).downto(1) | ||
flag = false # 初始化标志位 | ||
|
||
# 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 | ||
for j in 0...i | ||
if nums[j] > nums[j + 1] | ||
# 交换 nums[j] 与 nums[j + 1] | ||
nums[j], nums[j + 1] = nums[j + 1], nums[j] | ||
flag = true # 记录交换元素 | ||
end | ||
end | ||
|
||
break unless flag # 此轮“冒泡”未交换任何元素,直接跳出 | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
nums = [4, 1, 3, 1, 5, 2] | ||
bubble_sort(nums) | ||
puts "冒泡排序完成后 nums = #{nums}" | ||
|
||
nums1 = [4, 1, 3, 1, 5, 2] | ||
bubble_sort_with_flag(nums1) | ||
puts "冒泡排序完成后 nums = #{nums1}" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
=begin | ||
File: counting_sort.rb | ||
Created Time: 2024-05-02 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=end | ||
|
||
### 计数排序 ### | ||
def counting_sort_naive(nums) | ||
# 简单实现,无法用于排序对象 | ||
# 1. 统计数组最大元素 m | ||
m = 0 | ||
nums.each { |num| m = [m, num].max } | ||
# 2. 统计各数字的出现次数 | ||
# counter[num] 代表 num 的出现次数 | ||
counter = Array.new(m + 1, 0) | ||
nums.each { |num| counter[num] += 1 } | ||
# 3. 遍历 counter ,将各元素填入原数组 nums | ||
i = 0 | ||
for num in 0...(m + 1) | ||
(0...counter[num]).each do | ||
nums[i] = num | ||
i += 1 | ||
end | ||
end | ||
end | ||
|
||
### 计数排序 ### | ||
def counting_sort(nums) | ||
# 完整实现,可排序对象,并且是稳定排序 | ||
# 1. 统计数组最大元素 m | ||
m = nums.max | ||
# 2. 统计各数字的出现次数 | ||
# counter[num] 代表 num 的出现次数 | ||
counter = Array.new(m + 1, 0) | ||
nums.each { |num| counter[num] += 1 } | ||
# 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引” | ||
# 即 counter[num]-1 是 num 在 res 中最后一次出现的索引 | ||
(0...m).each { |i| counter[i + 1] += counter[i] } | ||
# 4. 倒序遍历 nums, 将各元素填入结果数组 res | ||
# 初始化数组 res 用于记录结果 | ||
n = nums.length | ||
res = Array.new(n, 0) | ||
(n - 1).downto(0).each do |i| | ||
num = nums[i] | ||
res[counter[num] - 1] = num # 将 num 放置到对应索引处 | ||
counter[num] -= 1 # 令前缀和自减 1 ,得到下次放置 num 的索引 | ||
end | ||
# 使用结果数组 res 覆盖原数组 nums | ||
(0...n).each { |i| nums[i] = res[i] } | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
nums = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4] | ||
|
||
counting_sort_naive(nums) | ||
puts "计数排序(无法排序对象)完成后 nums = #{nums}" | ||
|
||
nums1 = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4] | ||
counting_sort(nums1) | ||
puts "计数排序完成后 nums1 = #{nums1}" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
=begin | ||
File: selection_sort.rb | ||
Created Time: 2024-05-03 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=end | ||
|
||
### 获取元素 num 的第 k 位,其中 exp = 10^(k-1) ### | ||
def digit(num, exp) | ||
# 转入 exp 而非 k 可以避免在此重复执行昂贵的次方计算 | ||
(num / exp) % 10 | ||
end | ||
|
||
### 计数排序(根据 nums 第 k 位排序)### | ||
def counting_sort_digit(nums, exp) | ||
# 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组 | ||
counter = Array.new(10, 0) | ||
n = nums.length | ||
# 统计 0~9 各数字的出现次数 | ||
for i in 0...n | ||
d = digit(nums[i], exp) # 获取 nums[i] 第 k 位,记为 d | ||
counter[d] += 1 # 统计数字 d 的出现次数 | ||
end | ||
# 求前缀和,将“出现个数”转换为“数组索引” | ||
(1...10).each { |i| counter[i] += counter[i - 1] } | ||
# 倒序遍历,根据桶内统计结果,将各元素填入 res | ||
res = Array.new(n, 0) | ||
for i in (n - 1).downto(0) | ||
d = digit(nums[i], exp) | ||
j = counter[d] - 1 # 获取 d 在数组中的索引 j | ||
res[j] = nums[i] # 将当前元素填入索引 j | ||
counter[d] -= 1 # 将 d 的数量减 1 | ||
end | ||
# 使用结果覆盖原数组 nums | ||
(0...n).each { |i| nums[i] = res[i] } | ||
end | ||
|
||
### 基数排序 ### | ||
def radix_sort(nums) | ||
# 获取数组的最大元素,用于判断最大位数 | ||
m = nums.max | ||
# 按照从低位到高位的顺序遍历 | ||
exp = 1 | ||
while exp <= m | ||
# 对数组元素的第 k 位执行计数排序 | ||
# k = 1 -> exp = 1 | ||
# k = 2 -> exp = 10 | ||
# 即 exp = 10^(k-1) | ||
counting_sort_digit(nums, exp) | ||
exp *= 10 | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
# 基数排序 | ||
nums = [ | ||
10546151, | ||
35663510, | ||
42865989, | ||
34862445, | ||
81883077, | ||
88906420, | ||
72429244, | ||
30524779, | ||
82060337, | ||
63832996, | ||
] | ||
radix_sort(nums) | ||
puts "基数排序完成后 nums = #{nums}" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
=begin | ||
File: selection_sort.rb | ||
Created Time: 2024-05-03 | ||
Author: Xuan Khoa Tu Nguyen ([email protected]) | ||
=end | ||
|
||
### 选择排序 ### | ||
def selection_sort(nums) | ||
n = nums.length | ||
# 外循环:未排序区间为 [i, n-1] | ||
for i in 0...(n - 1) | ||
# 内循环:找到未排序区间内的最小元素 | ||
k = i | ||
for j in (i + 1)...n | ||
if nums[j] < nums[k] | ||
k = j # 记录最小元素的索引 | ||
end | ||
end | ||
# 将该最小元素与未排序区间的首个元素交换 | ||
nums[i], nums[k] = nums[k], nums[i] | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
if __FILE__ == $0 | ||
nums = [4, 1, 3, 1, 5, 2] | ||
selection_sort(nums) | ||
puts "选择排序完成后 nums = #{nums}" | ||
end |