mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-24 04:26:30 +08:00
feat: Add ruby code - chapter "array & linked list" (#1158)
* feat: add ruby code chapter array & linked list - array.rb - linked_list.rb - list.rb - my_list.rb * feat: add ruby code blocks * chore: fix convention
This commit is contained in:
parent
e799513173
commit
85ca4cce43
12 changed files with 687 additions and 0 deletions
107
codes/ruby/chapter_array_and_linkedlist/array.rb
Normal file
107
codes/ruby/chapter_array_and_linkedlist/array.rb
Normal file
|
@ -0,0 +1,107 @@
|
|||
=begin
|
||||
File: array.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### 随机访问元素 ###
|
||||
def random_access(nums)
|
||||
# 在区间 [0, nums.length) 中随机抽取一个数字
|
||||
random_index = Random.rand 0...(nums.length - 1)
|
||||
|
||||
# 获取并返回随机元素
|
||||
nums[random_index]
|
||||
end
|
||||
|
||||
|
||||
### 扩展数组长度 ###
|
||||
# 请注意,Ruby 的 Array 是动态数组,可以直接扩展
|
||||
# 为了方便学习,本函数将 Array 看作长度不可变的数组
|
||||
def extend(nums, enlarge)
|
||||
# 初始化一个扩展长度后的数组
|
||||
res = Array.new(nums.length + enlarge, 0)
|
||||
|
||||
# 将原数组中的所有元素复制到新数组
|
||||
for i in 0...nums.length
|
||||
res[i] = nums[i]
|
||||
end
|
||||
|
||||
# 返回扩展后的新数组
|
||||
res
|
||||
end
|
||||
|
||||
### 在数组的索引 index 处插入元素 num ###
|
||||
def insert(nums, num, index)
|
||||
# 把索引 index 以及之后的所有元素向后移动一位
|
||||
for i in (nums.length - 1).downto(index + 1)
|
||||
nums[i] = nums[i - 1]
|
||||
end
|
||||
|
||||
# 将 num 赋给 index 处的元素
|
||||
nums[index] = num
|
||||
end
|
||||
|
||||
|
||||
### 删除索引 index 处的元素 ###
|
||||
def remove(nums, index)
|
||||
# 把索引 index 之后的所有元素向前移动一位
|
||||
for i in index...nums.length
|
||||
nums[i] = nums[i + 1] || 0
|
||||
end
|
||||
end
|
||||
|
||||
### 遍历数组 ###
|
||||
def traverse(nums)
|
||||
count = 0
|
||||
|
||||
# 通过索引遍历数组
|
||||
for i in 0...nums.length
|
||||
count += nums[i]
|
||||
end
|
||||
|
||||
# 直接遍历数组元素
|
||||
for num in nums
|
||||
count += num
|
||||
end
|
||||
end
|
||||
|
||||
### 在数组中查找指定元素 ###
|
||||
def find(nums, target)
|
||||
for i in 0...nums.length
|
||||
return i if nums[i] == target
|
||||
end
|
||||
|
||||
-1
|
||||
end
|
||||
|
||||
|
||||
### Driver Code ###
|
||||
|
||||
# 初始化数组
|
||||
arr = Array.new(5, 0)
|
||||
puts "数组 arr = #{arr}"
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
puts "数组 nums = #{nums}"
|
||||
|
||||
# 随机访问
|
||||
random_num = random_access nums
|
||||
puts "在 nums 中获取随机元素 #{random_num}"
|
||||
|
||||
# 长度扩展
|
||||
nums = extend nums, 3
|
||||
puts "将数组长度扩展至 8 ,得到 nums = #{nums}"
|
||||
|
||||
# 插入元素
|
||||
insert nums, 6, 3
|
||||
puts "在索引 3 处插入数字 6 ,得到 nums = #{nums}"
|
||||
|
||||
# 删除元素
|
||||
remove nums, 2
|
||||
puts "删除索引 2 处的元素,得到 nums = #{nums}"
|
||||
|
||||
# 遍历数组
|
||||
traverse nums
|
||||
|
||||
# 查找元素
|
||||
index = find nums, 3
|
||||
puts "在 nums 中查找元素 3 ,得到索引 = #{index}";
|
82
codes/ruby/chapter_array_and_linkedlist/linked_list.rb
Normal file
82
codes/ruby/chapter_array_and_linkedlist/linked_list.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
=begin
|
||||
File: linked_list.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
require_relative '../utils/list_node'
|
||||
require_relative '../utils/print_util'
|
||||
|
||||
### 在链表的节点 n0 之后插入节点 _p ###
|
||||
# Ruby 的 `p` 是一个内置函数, `P` 是一个常量,所以可以使用 `_p` 代替
|
||||
def insert(n0, _p)
|
||||
n1 = n0.next
|
||||
_p.next = n1
|
||||
n0.next = _p
|
||||
end
|
||||
|
||||
### 删除链表的节点 n0 之后的首个节点 ###
|
||||
def remove(n0)
|
||||
return if n0.next.nil?
|
||||
|
||||
# n0 -> remove_node -> n1
|
||||
remove_node = n0.next
|
||||
n1 = remove_node.next
|
||||
n0.next = n1
|
||||
end
|
||||
|
||||
### 访问链表中索引为 index 的节点 ###
|
||||
def access(head, index)
|
||||
for i in 0...index
|
||||
return nil if head.nil?
|
||||
head = head.next
|
||||
end
|
||||
|
||||
head
|
||||
end
|
||||
|
||||
### 在链表中查找值为 target 的首个节点 ###
|
||||
def find(head, target)
|
||||
index = 0
|
||||
while head
|
||||
return index if head.val == target
|
||||
head = head.next
|
||||
index += 1
|
||||
end
|
||||
|
||||
-1
|
||||
end
|
||||
|
||||
### Driver Code ###
|
||||
|
||||
# 初始化链表
|
||||
# 初始化各个节点
|
||||
n0 = ListNode.new 1
|
||||
n1 = ListNode.new 3
|
||||
n2 = ListNode.new 2
|
||||
n3 = ListNode.new 5
|
||||
n4 = ListNode.new 4
|
||||
# 构建节点之间的引用
|
||||
n0.next = n1
|
||||
n1.next = n2
|
||||
n2.next = n3
|
||||
n3.next = n4
|
||||
puts "初始化的链表为"
|
||||
print_linked_list n0
|
||||
|
||||
# 插入节点
|
||||
insert n0, ListNode.new(0)
|
||||
print_linked_list n0
|
||||
|
||||
# 删除节点
|
||||
remove n0
|
||||
puts "删除节点后的链表为"
|
||||
print_linked_list n0
|
||||
|
||||
# 访问节点
|
||||
node = access n0, 3
|
||||
puts "链表中索引 3 处的节点的值 = #{node.val}"
|
||||
|
||||
# 查找节点
|
||||
index = find n0, 2
|
||||
puts "链表中值为 2 的节点的索引 = #{index}"
|
59
codes/ruby/chapter_array_and_linkedlist/list.rb
Normal file
59
codes/ruby/chapter_array_and_linkedlist/list.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
=begin
|
||||
File: list.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### Driver Code ###
|
||||
|
||||
# 初始化列表
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
puts "列表 nums = #{nums}"
|
||||
|
||||
# 访问元素
|
||||
num = nums[1]
|
||||
puts "访问索引 1 处的元素,得到 num = #{num}"
|
||||
|
||||
# 更新元素
|
||||
nums[1] = 0
|
||||
puts "将索引 1 处的元素更新为 0 ,得到 nums = #{nums}"
|
||||
|
||||
# 清空列表
|
||||
nums.clear
|
||||
puts "清空列表后 nums = #{nums}"
|
||||
|
||||
# 在尾部添加元素
|
||||
nums << 1
|
||||
nums << 3
|
||||
nums << 2
|
||||
nums << 5
|
||||
nums << 4
|
||||
puts "添加元素后 nums = #{nums}"
|
||||
|
||||
# 在中间插入元素
|
||||
nums.insert 3, 6
|
||||
puts "在索引 3 处插入元素 6 ,得到 nums = #{nums}"
|
||||
|
||||
# 删除元素
|
||||
nums.delete_at 3
|
||||
puts "删除索引 3 处的元素,得到 nums = #{nums}"
|
||||
|
||||
# 通过索引遍历列表
|
||||
count = 0
|
||||
for i in 0...nums.length
|
||||
count += nums[i]
|
||||
end
|
||||
|
||||
# 直接遍历列表元素
|
||||
count = 0
|
||||
nums.each do |x|
|
||||
count += x
|
||||
end
|
||||
|
||||
# 拼接两个列表
|
||||
nums1 = [6, 8, 7, 10, 9]
|
||||
nums += nums1
|
||||
puts "将列表 nums1 拼接到 nums 之后,得到 nums = #{nums}"
|
||||
|
||||
nums = nums.sort { |a, b| a <=> b }
|
||||
puts "排序列表后 nums = #{nums}"
|
131
codes/ruby/chapter_array_and_linkedlist/my_list.rb
Normal file
131
codes/ruby/chapter_array_and_linkedlist/my_list.rb
Normal file
|
@ -0,0 +1,131 @@
|
|||
=begin
|
||||
File: my_list.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### 列表类 ###
|
||||
class MyList
|
||||
attr_reader :size # 获取列表长度(当前元素数量)
|
||||
attr_reader :capacity # 获取列表容量
|
||||
|
||||
### 构造方法 ###
|
||||
def initialize
|
||||
@capacity = 10
|
||||
@size = 0
|
||||
@extend_ratio = 2
|
||||
@arr = Array.new capacity
|
||||
end
|
||||
|
||||
### 访问元素 ###
|
||||
def get(index)
|
||||
# 索引如果越界,则抛出异常,下同
|
||||
raise IndexError, "索引越界" if index < 0 || index >= size
|
||||
@arr[index]
|
||||
end
|
||||
|
||||
### 访问元素 ###
|
||||
def set(index, num)
|
||||
raise IndexError, "索引越界" if index < 0 || index >= size
|
||||
@arr[index] = num
|
||||
end
|
||||
|
||||
### 在尾部添加元素 ###
|
||||
def add(num)
|
||||
# 元素数量超出容量时,触发扩容机制
|
||||
extend_capacity if size == capacity
|
||||
@arr[size] = num
|
||||
|
||||
# 更新元素数量
|
||||
@size += 1
|
||||
end
|
||||
|
||||
### 在中间插入元素 ###
|
||||
def insert(index, num)
|
||||
raise IndexError, "索引越界" if index < 0 || index >= size
|
||||
|
||||
# 元素数量超出容量时,触发扩容机制
|
||||
extend_capacity if size == capacity
|
||||
|
||||
# 将索引 index 以及之后的元素都向后移动一位
|
||||
for j in (size - 1).downto(index)
|
||||
@arr[j + 1] = @arr[j]
|
||||
end
|
||||
@arr[index] = num
|
||||
|
||||
# 更新元素数量
|
||||
@size += 1
|
||||
end
|
||||
|
||||
### 删除元素 ###
|
||||
def remove(index)
|
||||
raise IndexError, "索引越界" if index < 0 || index >= size
|
||||
num = @arr[index]
|
||||
|
||||
# 将将索引 index 之后的元素都向前移动一位
|
||||
for j in index...size
|
||||
@arr[j] = @arr[j + 1]
|
||||
end
|
||||
|
||||
# 更新元素数量
|
||||
@size -= 1
|
||||
|
||||
# 返回被删除的元素
|
||||
num
|
||||
end
|
||||
|
||||
### 列表扩容 ###
|
||||
def extend_capacity
|
||||
# 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组复制到新数组
|
||||
arr = @arr.dup + Array.new(capacity * (@extend_ratio - 1))
|
||||
# 更新列表容量
|
||||
@capacity = arr.length
|
||||
end
|
||||
|
||||
### 将列表转换为数组 ###
|
||||
def to_array
|
||||
sz = size
|
||||
# 仅转换有效长度范围内的列表元素
|
||||
arr = Array.new sz
|
||||
for i in 0...sz
|
||||
arr[i] = get i
|
||||
end
|
||||
arr
|
||||
end
|
||||
end
|
||||
|
||||
### Driver Code ###
|
||||
|
||||
# 初始化列表
|
||||
nums = MyList.new
|
||||
|
||||
# 在尾部添加元素
|
||||
nums.add 1
|
||||
nums.add 3
|
||||
nums.add 2
|
||||
nums.add 5
|
||||
nums.add 4
|
||||
puts "列表 nums = #{nums.to_array} ,容量 = #{nums.capacity} ,长度 = #{nums.size}"
|
||||
|
||||
# 在中间插入元素
|
||||
nums.insert 3, 6
|
||||
puts "在索引 3 处插入数字 6 ,得到 nums = #{nums.to_array}"
|
||||
|
||||
# 删除元素
|
||||
nums.remove 3
|
||||
puts "删除索引 3 的元素,得到 nums = #{nums.to_array}"
|
||||
|
||||
# 访问元素
|
||||
num = nums.get 1
|
||||
puts "访问索引 1 处的元素,得到 num = #{num}"
|
||||
|
||||
# 更新元素
|
||||
nums.set 1, 0
|
||||
puts "将索引 1 处的元素更新为 0 ,得到 nums = #{nums.to_array}"
|
||||
|
||||
# 测试扩容机制
|
||||
for i in 0...10
|
||||
# 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
|
||||
nums.add i
|
||||
end
|
||||
puts "扩容后的列表 nums = #{nums.to_array} ,容量 = #{nums.capacity} ,长度 = #{nums.size}"
|
38
codes/ruby/utils/list_node.rb
Normal file
38
codes/ruby/utils/list_node.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
=begin
|
||||
File: list_node.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### 链表节点类 ###
|
||||
class ListNode
|
||||
attr_accessor :val # 节点值
|
||||
attr_accessor :next # 指向下一节点的引用
|
||||
|
||||
def initialize(val=nil, next_node=nil)
|
||||
@val = val || 0
|
||||
@next = next_node
|
||||
end
|
||||
end
|
||||
|
||||
### 将列表序列化为链表 ###
|
||||
def arr_to_linked_list(arr)
|
||||
head = current = ListNode.new arr[0]
|
||||
|
||||
for i in 1...arr.length
|
||||
current.next = ListNode.new arr[i]
|
||||
current = current.next
|
||||
end
|
||||
|
||||
head
|
||||
end
|
||||
|
||||
### 将链表反序列化为列表 ###
|
||||
def linked_list_to_arr(head)
|
||||
arr = []
|
||||
|
||||
while head
|
||||
arr << head.val
|
||||
head = head.next
|
||||
end
|
||||
end
|
15
codes/ruby/utils/print_util.rb
Normal file
15
codes/ruby/utils/print_util.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
=begin
|
||||
File: print_util.rb
|
||||
Created Time: 2024-03-18
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### 打印链表 ###
|
||||
def print_linked_list(head)
|
||||
list = []
|
||||
while head
|
||||
list << head.val
|
||||
head = head.next
|
||||
end
|
||||
puts "#{list.join(" -> ")}"
|
||||
end
|
|
@ -121,6 +121,14 @@
|
|||
var nums = [_]i32{ 1, 3, 2, 5, 4 };
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="array.rb"
|
||||
# 初始化数组
|
||||
arr = Array.new(5, 0)
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E6%95%B0%E7%BB%84%0Aarr%20%3D%20%5B0%5D%20*%205%20%20%23%20%5B%200,%200,%200,%200,%200%20%5D%0Anums%20%3D%20%5B1,%203,%202,%205,%204%5D&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
|
|
@ -190,6 +190,21 @@
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=""
|
||||
# 链表节点类
|
||||
class ListNode
|
||||
attr_accessor :val # 节点值
|
||||
attr_accessor :next # 指向下一节点的引用
|
||||
|
||||
def initialize(val=nil, next_node=nil)
|
||||
@val = val || 0
|
||||
@next = next_node
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## 链表常用操作
|
||||
|
||||
### 初始化链表
|
||||
|
@ -418,6 +433,23 @@
|
|||
n3.next = &n4;
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=linked_list.rb
|
||||
# 初始化链表 1 -> 3 -> 2 -> 5 -> 4
|
||||
# 初始化各个节点
|
||||
n0 = ListNode.new 1
|
||||
n1 = ListNode.new 3
|
||||
n2 = ListNode.new 2
|
||||
n3 = ListNode.new 5
|
||||
n4 = ListNode.new 4
|
||||
# 构建节点之间的引用
|
||||
n0.next = n1
|
||||
n1.next = n2
|
||||
n2.next = n3
|
||||
n3.next = n4
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=class%20ListNode%3A%0A%20%20%20%20%22%22%22%E9%93%BE%E8%A1%A8%E8%8A%82%E7%82%B9%E7%B1%BB%22%22%22%0A%20%20%20%20def%20__init__%28self,%20val%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.val%3A%20int%20%3D%20val%20%20%23%20%E8%8A%82%E7%82%B9%E5%80%BC%0A%20%20%20%20%20%20%20%20self.next%3A%20ListNode%20%7C%20None%20%3D%20None%20%20%23%20%E5%90%8E%E7%BB%A7%E8%8A%82%E7%82%B9%E5%BC%95%E7%94%A8%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E9%93%BE%E8%A1%A8%201%20-%3E%203%20-%3E%202%20-%3E%205%20-%3E%204%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%90%84%E4%B8%AA%E8%8A%82%E7%82%B9%0A%20%20%20%20n0%20%3D%20ListNode%281%29%0A%20%20%20%20n1%20%3D%20ListNode%283%29%0A%20%20%20%20n2%20%3D%20ListNode%282%29%0A%20%20%20%20n3%20%3D%20ListNode%285%29%0A%20%20%20%20n4%20%3D%20ListNode%284%29%0A%20%20%20%20%23%20%E6%9E%84%E5%BB%BA%E8%8A%82%E7%82%B9%E4%B9%8B%E9%97%B4%E7%9A%84%E5%BC%95%E7%94%A8%0A%20%20%20%20n0.next%20%3D%20n1%0A%20%20%20%20n1.next%20%3D%20n2%0A%20%20%20%20n2.next%20%3D%20n3%0A%20%20%20%20n3.next%20%3D%20n4&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -690,6 +722,23 @@
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=""
|
||||
# 双向链表节点类
|
||||
class ListNode
|
||||
attr_accessor :val # 节点值
|
||||
attr_accessor :next # 指向后继节点的引用
|
||||
attr_accessor :prev # 指向前驱节点的引用
|
||||
|
||||
def initialize(val=nil, next_node=nil, prev_node=nil)
|
||||
@val = val || 0
|
||||
@next = next_node
|
||||
@prev = prev_node
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
![常见链表种类](linked_list.assets/linkedlist_common_types.png)
|
||||
|
||||
## 链表典型应用
|
||||
|
|
|
@ -146,6 +146,16 @@
|
|||
try nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 初始化列表
|
||||
# 无初始值
|
||||
nums1 = []
|
||||
# 有初始值
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%97%E8%A1%A8%0A%20%20%20%20%23%20%E6%97%A0%E5%88%9D%E5%A7%8B%E5%80%BC%0A%20%20%20%20nums1%20%3D%20%5B%5D%0A%20%20%20%20%23%20%E6%9C%89%E5%88%9D%E5%A7%8B%E5%80%BC%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -278,6 +288,15 @@
|
|||
nums.items[1] = 0; // 将索引 1 处的元素更新为 0
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 访问元素
|
||||
num = nums[1]
|
||||
# 更新元素
|
||||
nums[1] = 0
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%97%E8%A1%A8%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%0A%20%20%20%20%23%20%E8%AE%BF%E9%97%AE%E5%85%83%E7%B4%A0%0A%20%20%20%20num%20%3D%20nums%5B1%5D%20%20%23%20%E8%AE%BF%E9%97%AE%E7%B4%A2%E5%BC%95%201%20%E5%A4%84%E7%9A%84%E5%85%83%E7%B4%A0%0A%0A%20%20%20%20%23%20%E6%9B%B4%E6%96%B0%E5%85%83%E7%B4%A0%0A%20%20%20%20nums%5B1%5D%20%3D%200%20%20%20%20%23%20%E5%B0%86%E7%B4%A2%E5%BC%95%201%20%E5%A4%84%E7%9A%84%E5%85%83%E7%B4%A0%E6%9B%B4%E6%96%B0%E4%B8%BA%200&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -532,6 +551,26 @@
|
|||
_ = nums.orderedRemove(3); // 删除索引 3 处的元素
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 清空列表
|
||||
nums.clear
|
||||
|
||||
# 在尾部添加元素
|
||||
nums << 1
|
||||
nums << 3
|
||||
nums << 2
|
||||
nums << 5
|
||||
nums << 4
|
||||
|
||||
# 在中间插入元素
|
||||
nums.insert 3, 6
|
||||
|
||||
# 删除元素
|
||||
nums.delete_at 3
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E6%9C%89%E5%88%9D%E5%A7%8B%E5%80%BC%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%E6%B8%85%E7%A9%BA%E5%88%97%E8%A1%A8%0A%20%20%20%20nums.clear%28%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%9C%A8%E5%B0%BE%E9%83%A8%E6%B7%BB%E5%8A%A0%E5%85%83%E7%B4%A0%0A%20%20%20%20nums.append%281%29%0A%20%20%20%20nums.append%283%29%0A%20%20%20%20nums.append%282%29%0A%20%20%20%20nums.append%285%29%0A%20%20%20%20nums.append%284%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%9C%A8%E4%B8%AD%E9%97%B4%E6%8F%92%E5%85%A5%E5%85%83%E7%B4%A0%0A%20%20%20%20nums.insert%283,%206%29%20%20%23%20%E5%9C%A8%E7%B4%A2%E5%BC%95%203%20%E5%A4%84%E6%8F%92%E5%85%A5%E6%95%B0%E5%AD%97%206%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%88%A0%E9%99%A4%E5%85%83%E7%B4%A0%0A%20%20%20%20nums.pop%283%29%20%20%20%20%20%20%20%20%23%20%E5%88%A0%E9%99%A4%E7%B4%A2%E5%BC%95%203%20%E5%A4%84%E7%9A%84%E5%85%83%E7%B4%A0&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -734,6 +773,22 @@
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 通过索引遍历列表
|
||||
count = 0
|
||||
for i in 0...nums.length
|
||||
count += nums[i]
|
||||
end
|
||||
|
||||
# 直接遍历列表元素
|
||||
count = 0
|
||||
for num in nums
|
||||
count += num
|
||||
end
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%97%E8%A1%A8%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%E9%80%9A%E8%BF%87%E7%B4%A2%E5%BC%95%E9%81%8D%E5%8E%86%E5%88%97%E8%A1%A8%0A%20%20%20%20count%20%3D%200%0A%20%20%20%20for%20i%20in%20range%28len%28nums%29%29%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20nums%5Bi%5D%0A%0A%20%20%20%20%23%20%E7%9B%B4%E6%8E%A5%E9%81%8D%E5%8E%86%E5%88%97%E8%A1%A8%E5%85%83%E7%B4%A0%0A%20%20%20%20for%20num%20in%20nums%3A%0A%20%20%20%20%20%20%20%20count%20%2B%3D%20num&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -847,6 +902,14 @@
|
|||
try nums.insertSlice(nums.items.len, nums1.items); // 将列表 nums1 拼接到 nums 之后
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 拼接两个列表
|
||||
nums1 = [6, 8, 7, 10, 9]
|
||||
nums += nums1
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%97%E8%A1%A8%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%E6%8B%BC%E6%8E%A5%E4%B8%A4%E4%B8%AA%E5%88%97%E8%A1%A8%0A%20%20%20%20nums1%20%3D%20%5B6,%208,%207,%2010,%209%5D%0A%20%20%20%20nums%20%2B%3D%20nums1%20%20%23%20%E5%B0%86%E5%88%97%E8%A1%A8%20nums1%20%E6%8B%BC%E6%8E%A5%E5%88%B0%20nums%20%E4%B9%8B%E5%90%8E&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
@ -945,6 +1008,13 @@
|
|||
std.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# 排序列表
|
||||
nums = nums.sort { |a, b| a <=> b }
|
||||
```
|
||||
|
||||
??? pythontutor "可视化运行"
|
||||
|
||||
https://pythontutor.com/render.html#code=%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%97%E8%A1%A8%0A%20%20%20%20nums%20%3D%20%5B1,%203,%202,%205,%204%5D%0A%20%20%20%20%0A%20%20%20%20%23%20%E6%8E%92%E5%BA%8F%E5%88%97%E8%A1%A8%0A%20%20%20%20nums.sort%28%29%20%20%23%20%E6%8E%92%E5%BA%8F%E5%90%8E%EF%BC%8C%E5%88%97%E8%A1%A8%E5%85%83%E7%B4%A0%E4%BB%8E%E5%B0%8F%E5%88%B0%E5%A4%A7%E6%8E%92%E5%88%97&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
|
||||
|
|
|
@ -119,6 +119,14 @@ Arrays can be initialized in two ways depending on the needs: either without ini
|
|||
var nums = [_]i32{ 1, 3, 2, 5, 4 };
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="array.rb"
|
||||
# Initialize array
|
||||
arr = Array.new(5, 0) # [ 0, 0, 0, 0, 0 ]
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
```
|
||||
|
||||
### Accessing Elements
|
||||
|
||||
Elements in an array are stored in contiguous memory spaces, making it simpler to compute each element's memory address. The formula shown in the Figure below aids in determining an element's memory address, utilizing the array's memory address (specifically, the first element's address) and the element's index. This computation streamlines direct access to the desired element.
|
||||
|
|
|
@ -185,6 +185,22 @@ As the code below illustrates, a `ListNode` in a linked list, besides holding a
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=""
|
||||
# Linked List Node Class
|
||||
class ListNode
|
||||
attr_accessor :val # Node value
|
||||
attr_accessor :next # Reference to the next node
|
||||
|
||||
def initialize(val=nil, next_node=nil)
|
||||
@val = val || 0
|
||||
@next = next_node
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
## Common Operations on Linked Lists
|
||||
|
||||
### Initializing a Linked List
|
||||
|
@ -402,6 +418,23 @@ Constructing a linked list is a two-step process: first, initializing each node
|
|||
n3.next = &n4;
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=linked_list.rb
|
||||
# Initialize linked list 1 -> 3 -> 2 -> 5 -> 4
|
||||
# Initialize each node
|
||||
n0 = ListNode.new 1
|
||||
n1 = ListNode.new 3
|
||||
n2 = ListNode.new 2
|
||||
n3 = ListNode.new 5
|
||||
n4 = ListNode.new 4
|
||||
# Build references between nodes
|
||||
n0.next = n1
|
||||
n1.next = n2
|
||||
n2.next = n3
|
||||
n3.next = n4
|
||||
```
|
||||
|
||||
The array as a whole is a variable, for instance, the array `nums` includes elements like `nums[0]`, `nums[1]`, and so on, whereas a linked list is made up of several distinct node objects. **We typically refer to a linked list by its head node**, for example, the linked list in the previous code snippet is referred to as `n0`.
|
||||
|
||||
### Inserting a Node
|
||||
|
@ -664,6 +697,23 @@ As shown in the figure, there are three common types of linked lists.
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=""
|
||||
# Bidirectional linked list node class
|
||||
class ListNode
|
||||
attr_accessor :val # Node value
|
||||
attr_accessor :next # Reference to the successor node
|
||||
attr_accessor :prev # Reference to the predecessor node
|
||||
|
||||
def initialize(val=nil, next_node=nil, prev_node=nil)
|
||||
@val = val || 0
|
||||
@next = next_node
|
||||
@prev = prev_node
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
![Common Types of Linked Lists](linked_list.assets/linkedlist_common_types.png)
|
||||
|
||||
## Typical Applications of Linked Lists
|
||||
|
|
|
@ -141,6 +141,16 @@ We typically use two initialization methods: "without initial values" and "with
|
|||
try nums.appendSlice(&[_]i32{ 1, 3, 2, 5, 4 });
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Initialize list
|
||||
# Without initial values
|
||||
nums1 = []
|
||||
# With initial values
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
```
|
||||
|
||||
### Accessing Elements
|
||||
|
||||
Lists are essentially arrays, thus they can access and update elements in $O(1)$ time, which is very efficient.
|
||||
|
@ -266,6 +276,15 @@ Lists are essentially arrays, thus they can access and update elements in $O(1)$
|
|||
nums.items[1] = 0; // Update the element at index 1 to 0
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Access elements
|
||||
num = nums[1]
|
||||
# Update elements
|
||||
nums[1] = 0
|
||||
```
|
||||
|
||||
### Inserting and Removing Elements
|
||||
|
||||
Compared to arrays, lists offer more flexibility in adding and removing elements. While adding elements to the end of a list is an $O(1)$ operation, the efficiency of inserting and removing elements elsewhere in the list remains the same as in arrays, with a time complexity of $O(n)$.
|
||||
|
@ -502,6 +521,26 @@ Compared to arrays, lists offer more flexibility in adding and removing elements
|
|||
_ = nums.orderedRemove(3); // Remove the element at index 3
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Clear list
|
||||
nums.clear
|
||||
|
||||
# Append elements at the end
|
||||
nums << 1
|
||||
nums << 3
|
||||
nums << 2
|
||||
nums << 5
|
||||
nums << 4
|
||||
|
||||
# Insert element in the middle
|
||||
nums.insert 3, 6 # Insert number 6 at index 3
|
||||
|
||||
# Remove elements
|
||||
nums.delete_at 3 # Remove the element at index 3
|
||||
```
|
||||
|
||||
### Iterating the List
|
||||
|
||||
Similar to arrays, lists can be iterated either by using indices or by directly iterating through each element.
|
||||
|
@ -691,6 +730,22 @@ Similar to arrays, lists can be iterated either by using indices or by directly
|
|||
}
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Iterate through the list by index
|
||||
count = 0
|
||||
for i in 0...nums.length
|
||||
count += nums[i]
|
||||
end
|
||||
|
||||
# Iterate directly though list elements
|
||||
count = 0
|
||||
for num in nums
|
||||
count += num
|
||||
end
|
||||
```
|
||||
|
||||
### Concatenating Lists
|
||||
|
||||
Given a new list `nums1`, we can append it to the end of the original list.
|
||||
|
@ -798,6 +853,14 @@ Given a new list `nums1`, we can append it to the end of the original list.
|
|||
try nums.insertSlice(nums.items.len, nums1.items); // Concatenate nums1 to the end of nums
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Concatenate two lists
|
||||
nums1 = [6, 8, 7, 10, 9]
|
||||
nums += nums1
|
||||
```
|
||||
|
||||
### Sorting the List
|
||||
|
||||
Once the list is sorted, we can employ algorithms commonly used in array-related algorithm problems, such as "binary search" and "two-pointer" algorithms.
|
||||
|
@ -891,6 +954,13 @@ Once the list is sorted, we can employ algorithms commonly used in array-related
|
|||
std.sort.sort(i32, nums.items, {}, comptime std.sort.asc(i32));
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="list.rb"
|
||||
# Sort the list
|
||||
nums = nums.sort { |a, b| a <=> b }
|
||||
```
|
||||
|
||||
## List Implementation
|
||||
|
||||
Many programming languages come with built-in lists, including Java, C++, Python, etc. Their implementations tend to be intricate, featuring carefully considered settings for various parameters, like initial capacity and expansion factors. Readers who are curious can delve into the source code for further learning.
|
||||
|
|
Loading…
Reference in a new issue