forked from krahets/hello-algo
-
Notifications
You must be signed in to change notification settings - Fork 0
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 stack and queue (krahets#1230)
- Loading branch information
1 parent
f901a31
commit e121665
Showing
9 changed files
with
794 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,144 @@ | ||
=begin | ||
File: array_deque.rb | ||
Created Time: 2024-04-05 | ||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) | ||
=end | ||
|
||
### 基于环形数组实现的双向队列 ### | ||
class ArrayDeque | ||
### 获取双向队列的长度 ### | ||
attr_reader :size | ||
|
||
### 构造方法 ### | ||
def initialize(capacity) | ||
@nums = Array.new(capacity, 0) | ||
@front = 0 | ||
@size = 0 | ||
end | ||
|
||
### 获取双向队列的容量 ### | ||
def capacity | ||
@nums.length | ||
end | ||
|
||
### 判断双向队列是否为空 ### | ||
def is_empty? | ||
size.zero? | ||
end | ||
|
||
### 队首入队 ### | ||
def push_first(num) | ||
if size == capacity | ||
puts '双向队列已满' | ||
return | ||
end | ||
|
||
# 队首指针向左移动一位 | ||
# 通过取余操作实现 front 越过数组头部后回到尾部 | ||
@front = index(@front - 1) | ||
# 将 num 添加至队首 | ||
@nums[@front] = num | ||
@size += 1 | ||
end | ||
|
||
### 队尾入队 ### | ||
def push_last(num) | ||
if size == capacity | ||
puts '双向队列已满' | ||
return | ||
end | ||
|
||
# 计算队尾指针,指向队尾索引 + 1 | ||
rear = index(@front + size) | ||
# 将 num 添加至队尾 | ||
@nums[rear] = num | ||
@size += 1 | ||
end | ||
|
||
### 队首出队 ### | ||
def pop_first | ||
num = peek_first | ||
# 队首指针向后移动一位 | ||
@front = index(@front + 1) | ||
@size -= 1 | ||
num | ||
end | ||
|
||
### 队尾出队 ### | ||
def pop_last | ||
num = peek_last | ||
@size -= 1 | ||
num | ||
end | ||
|
||
### 访问队首元素 ### | ||
def peek_first | ||
raise IndexError, '双向队列为空' if is_empty? | ||
|
||
@nums[@front] | ||
end | ||
|
||
### 访问队尾元素 ### | ||
def peek_last | ||
raise IndexError, '双向队列为空' if is_empty? | ||
|
||
# 计算尾元素索引 | ||
last = index(@front + size - 1) | ||
@nums[last] | ||
end | ||
|
||
### 返回数组用于打印 ### | ||
def to_array | ||
# 仅转换有效长度范围内的列表元素 | ||
res = [] | ||
for i in 0...size | ||
res << @nums[index(@front + i)] | ||
end | ||
res | ||
end | ||
|
||
private | ||
|
||
### 计算环形数组索引 ### | ||
def index(i) | ||
# 通过取余操作实现数组首尾相连 | ||
# 当 i 越过数组尾部后,回到头部 | ||
# 当 i 越过数组头部后,回到尾部 | ||
(i + capacity) % capacity | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
|
||
# 初始化双向队列 | ||
deque = ArrayDeque.new(10) | ||
deque.push_last(3) | ||
deque.push_last(2) | ||
deque.push_last(5) | ||
puts "双向队列 deque = #{deque.to_array}" | ||
|
||
# 访问元素 | ||
peek_first = deque.peek_first | ||
puts "队首元素 peek_first = #{peek_first}" | ||
peek_last = deque.peek_last | ||
puts "队尾元素 peek_last = #{peek_last}" | ||
|
||
# 元素入队 | ||
deque.push_last(4) | ||
puts "元素 4 队尾入队后 deque = #{deque.to_array}" | ||
deque.push_first(1) | ||
puts "元素 1 队尾入队后 deque = #{deque.to_array}" | ||
|
||
# 元素出队 | ||
pop_last = deque.pop_last | ||
puts "队尾出队元素 = #{pop_last},队尾出队后 deque = #{deque.to_array}" | ||
pop_first = deque.pop_first | ||
puts "队尾出队元素 = #{pop_first},队尾出队后 deque = #{deque.to_array}" | ||
|
||
# 获取双向队列的长度 | ||
size = deque.size | ||
puts "双向队列长度 size = #{size}" | ||
|
||
# 判断双向队列是否为空 | ||
is_empty = deque.is_empty? | ||
puts "双向队列是否为空 = #{is_empty}" |
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,106 @@ | ||
=begin | ||
File: array_queue.rb | ||
Created Time: 2024-04-05 | ||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) | ||
=end | ||
|
||
### 基于环形数组实现的队列 ### | ||
class ArrayQueue | ||
### 获取队列的长度 ### | ||
attr_reader :size | ||
|
||
### 构造方法 ### | ||
def initialize(size) | ||
@nums = Array.new(size, 0) # 用于存储队列元素的数组 | ||
@front = 0 # 队首指针,指向队首元素 | ||
@size = 0 # 队列长度 | ||
end | ||
|
||
### 获取队列的容量 ### | ||
def capacity | ||
@nums.length | ||
end | ||
|
||
### 判断队列是否为空 ### | ||
def is_empty? | ||
size.zero? | ||
end | ||
|
||
### 入队 ### | ||
def push(num) | ||
raise IndexError, '队列已满' if size == capacity | ||
|
||
# 计算队尾指针,指向队尾索引 + 1 | ||
# 通过取余操作实现 rear 越过数组尾部后回到头部 | ||
rear = (@front + size) % capacity | ||
# 将 num 添加至队尾 | ||
@nums[rear] = num | ||
@size += 1 | ||
end | ||
|
||
### 出队 ### | ||
def pop | ||
num = peek | ||
# 队首指针向后移动一位,若越过尾部,则返回到数组头部 | ||
@front = (@front + 1) % capacity | ||
@size -= 1 | ||
num | ||
end | ||
|
||
### 访问队首元素 ### | ||
def peek | ||
raise IndexError, '队列为空' if is_empty? | ||
|
||
@nums[@front] | ||
end | ||
|
||
### 返回列表用于打印 ### | ||
def to_array | ||
res = Array.new(size, 0) | ||
j = @front | ||
|
||
for i in 0...size | ||
res[i] = @nums[j % capacity] | ||
j += 1 | ||
end | ||
|
||
res | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
|
||
# 初始化队列 | ||
queue = ArrayQueue.new(10) | ||
|
||
# 元素入队 | ||
queue.push(1) | ||
queue.push(3) | ||
queue.push(2) | ||
queue.push(5) | ||
queue.push(4) | ||
puts "队列 queue = #{queue.to_array}" | ||
|
||
# 访问队首元素 | ||
peek = queue.peek | ||
puts "队首元素 peek = #{peek}" | ||
|
||
# 元素出队 | ||
pop = queue.pop | ||
puts "出队元素 pop = #{pop}" | ||
puts "出队后 queue = #{queue.to_array}" | ||
|
||
# 获取队列的长度 | ||
size = queue.size | ||
puts "队列长度 size = #{size}" | ||
|
||
# 判断队列是否为空 | ||
is_empty = queue.is_empty? | ||
puts "队列是否为空 = #{is_empty}" | ||
|
||
# 测试环形数组 | ||
for i in 0...10 | ||
queue.push(i) | ||
queue.pop | ||
puts "第 #{i} 轮入队 + 出队后 queue = #{queue.to_array}" | ||
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,77 @@ | ||
=begin | ||
File: array_stack.rb | ||
Created Time: 2024-04-06 | ||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) | ||
=end | ||
|
||
### 基于数组实现的栈 ### | ||
class ArrayStack | ||
### 构造方法 ### | ||
def initialize | ||
@stack = [] | ||
end | ||
|
||
### 获取栈的长度 ### | ||
def size | ||
@stack.length | ||
end | ||
|
||
### 判断栈是否为空 ### | ||
def is_empty? | ||
@stack.empty? | ||
end | ||
|
||
### 入栈 ### | ||
def push(item) | ||
@stack << item | ||
end | ||
|
||
### 出栈 ### | ||
def pop | ||
raise IndexError, '栈为空' if is_empty? | ||
|
||
@stack.pop | ||
end | ||
|
||
### 访问栈顶元素 ### | ||
def peek | ||
raise IndexError, '栈为空' if is_empty? | ||
|
||
@stack.last | ||
end | ||
|
||
### 返回列表用于打印 ### | ||
def to_array | ||
@stack | ||
end | ||
end | ||
|
||
### Driver Code ### | ||
|
||
# 初始化栈 | ||
stack = ArrayStack.new | ||
|
||
# 元素入栈 | ||
stack.push(1) | ||
stack.push(3) | ||
stack.push(2) | ||
stack.push(5) | ||
stack.push(4) | ||
puts "栈 stack = #{stack.to_array}" | ||
|
||
# 访问栈顶元素 | ||
peek = stack.peek | ||
puts "栈顶元素 peek = #{peek}" | ||
|
||
# 元素出栈 | ||
pop = stack.pop | ||
puts "出栈元素 pop = #{pop}" | ||
puts "出栈后 stack = #{stack.to_array}" | ||
|
||
# 获取栈的长度 | ||
size = stack.size | ||
puts "栈的长度 size = #{size}" | ||
|
||
# 判断是否为空 | ||
is_empty = stack.is_empty? | ||
puts "栈是否为空 = #{is_empty}" |
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,41 @@ | ||
=begin | ||
File: deque.rb | ||
Created Time: 2024-04-06 | ||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com) | ||
=end | ||
|
||
### Driver Code ### | ||
|
||
# 初始化双向队列 | ||
# Ruby 没有内直的双端队列,只能把 Array 当作双端队列来使用 | ||
deque = [] | ||
|
||
# 元素如队 | ||
deque << 2 | ||
deque << 5 | ||
deque << 4 | ||
# 请注意,由于是数组,Array#unshift 方法的时间复杂度为 O(n) | ||
deque.unshift(3) | ||
deque.unshift(1) | ||
puts "双向队列 deque = #{deque}" | ||
|
||
# 访问元素 | ||
peek_first = deque.first | ||
puts "队首元素 peek_first = #{peek_first}" | ||
peek_last = deque.last | ||
puts "队尾元素 peek_last = #{peek_last}" | ||
|
||
# 元素出队 | ||
# 请注意,由于是数组, Array#shift 方法的时间复杂度为 O(n) | ||
pop_front = deque.shift | ||
puts "队首出队元素 pop_front = #{pop_front},队首出队后 deque = #{deque}" | ||
pop_back = deque.pop | ||
puts "队尾出队元素 pop_back = #{pop_back}, 队尾出队后 deque = #{deque}" | ||
|
||
# 获取双向队列的长度 | ||
size = deque.length | ||
puts "双向队列长度 size = #{size}" | ||
|
||
# 判断双向队列是否为空 | ||
is_empty = size.zero? | ||
puts "双向队列是否为空 = #{is_empty}" |
Oops, something went wrong.