mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 12:06:27 +08:00
feat: add ruby code - chapter stack and queue (#1230)
This commit is contained in:
parent
f901a31bae
commit
e121665772
9 changed files with 794 additions and 0 deletions
144
codes/ruby/chapter_stack_and_queue/array_deque.rb
Normal file
144
codes/ruby/chapter_stack_and_queue/array_deque.rb
Normal file
|
@ -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}"
|
106
codes/ruby/chapter_stack_and_queue/array_queue.rb
Normal file
106
codes/ruby/chapter_stack_and_queue/array_queue.rb
Normal file
|
@ -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
|
77
codes/ruby/chapter_stack_and_queue/array_stack.rb
Normal file
77
codes/ruby/chapter_stack_and_queue/array_stack.rb
Normal file
|
@ -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}"
|
41
codes/ruby/chapter_stack_and_queue/deque.rb
Normal file
41
codes/ruby/chapter_stack_and_queue/deque.rb
Normal file
|
@ -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}"
|
167
codes/ruby/chapter_stack_and_queue/linkedlist_deque.rb
Normal file
167
codes/ruby/chapter_stack_and_queue/linkedlist_deque.rb
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
=begin
|
||||||
|
File: linkedlist_deque.rb
|
||||||
|
Created Time: 2024-04-06
|
||||||
|
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||||
|
=end
|
||||||
|
|
||||||
|
### 双向链表节点
|
||||||
|
class ListNode
|
||||||
|
attr_accessor :val
|
||||||
|
attr_accessor :next # 后继节点引用
|
||||||
|
attr_accessor :prev # 前躯节点引用
|
||||||
|
|
||||||
|
### 构造方法 ###
|
||||||
|
def initialize(val)
|
||||||
|
@val = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
### 基于双向链表实现的双向队列 ###
|
||||||
|
class LinkedListDeque
|
||||||
|
### 获取双向队列的长度 ###
|
||||||
|
attr_reader :size
|
||||||
|
|
||||||
|
### 构造方法 ###
|
||||||
|
def initialize
|
||||||
|
@front = nil # 头节点 front
|
||||||
|
@rear = nil # 尾节点 rear
|
||||||
|
@size = 0 # 双向队列的长度
|
||||||
|
end
|
||||||
|
|
||||||
|
### 判断双向队列是否为空 ###
|
||||||
|
def is_empty?
|
||||||
|
size.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
### 入队操作 ###
|
||||||
|
def push(num, is_front)
|
||||||
|
node = ListNode.new(num)
|
||||||
|
# 若链表为空, 则令 front 和 rear 都指向 node
|
||||||
|
if is_empty?
|
||||||
|
@front = @rear = node
|
||||||
|
# 队首入队操作
|
||||||
|
elsif is_front
|
||||||
|
# 将 node 添加至链表头部
|
||||||
|
@front.prev = node
|
||||||
|
node.next = @front
|
||||||
|
@front = node # 更新头节点
|
||||||
|
# 队尾入队操作
|
||||||
|
else
|
||||||
|
# 将 node 添加至链表尾部
|
||||||
|
@rear.next = node
|
||||||
|
node.prev = @rear
|
||||||
|
@rear = node # 更新尾节点
|
||||||
|
end
|
||||||
|
@size += 1 # 更新队列长度
|
||||||
|
end
|
||||||
|
|
||||||
|
### 队首入队 ###
|
||||||
|
def push_first(num)
|
||||||
|
push(num, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
### 队尾入队 ###
|
||||||
|
def push_last(num)
|
||||||
|
push(num, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
### 出队操作 ###
|
||||||
|
def pop(is_front)
|
||||||
|
raise IndexError, '双向队列为空' if is_empty?
|
||||||
|
|
||||||
|
# 队首出队操作
|
||||||
|
if is_front
|
||||||
|
val = @front.val # 暂存头节点值
|
||||||
|
# 删除头节点
|
||||||
|
fnext = @front.next
|
||||||
|
unless fnext.nil?
|
||||||
|
fnext.prev = nil
|
||||||
|
@front.next = nil
|
||||||
|
end
|
||||||
|
@front = fnext # 更新头节点
|
||||||
|
# 队尾出队操作
|
||||||
|
else
|
||||||
|
val = @rear.val # 暂存尾节点值
|
||||||
|
# 删除尾节点
|
||||||
|
rprev = @rear.prev
|
||||||
|
unless rprev.nil?
|
||||||
|
rprev.next = nil
|
||||||
|
@rear.prev = nil
|
||||||
|
end
|
||||||
|
@rear = rprev # 更新尾节点
|
||||||
|
end
|
||||||
|
@size -= 1 # 更新队列长度
|
||||||
|
|
||||||
|
val
|
||||||
|
end
|
||||||
|
|
||||||
|
### 队首出队 ###
|
||||||
|
def pop_first
|
||||||
|
pop(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
### 队首出队 ###
|
||||||
|
def pop_last
|
||||||
|
pop(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
### 访问队首元素 ###
|
||||||
|
def peek_first
|
||||||
|
raise IndexError, '双向队列为空' if is_empty?
|
||||||
|
|
||||||
|
@front.val
|
||||||
|
end
|
||||||
|
|
||||||
|
### 访问队尾元素 ###
|
||||||
|
def peek_last
|
||||||
|
raise IndexError, '双向队列为空' if is_empty?
|
||||||
|
|
||||||
|
@rear.val
|
||||||
|
end
|
||||||
|
|
||||||
|
### 返回数组用于打印 ###
|
||||||
|
def to_array
|
||||||
|
node = @front
|
||||||
|
res = Array.new(size, 0)
|
||||||
|
for i in 0...size
|
||||||
|
res[i] = node.val
|
||||||
|
node = node.next
|
||||||
|
end
|
||||||
|
res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
### Driver Code ###
|
||||||
|
|
||||||
|
# 初始化双向队列
|
||||||
|
deque = LinkedListDeque.new
|
||||||
|
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}"
|
100
codes/ruby/chapter_stack_and_queue/linkedlist_queue.rb
Normal file
100
codes/ruby/chapter_stack_and_queue/linkedlist_queue.rb
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
=begin
|
||||||
|
File: linkedlist_queue.rb
|
||||||
|
Created Time: 2024-04-06
|
||||||
|
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||||
|
=end
|
||||||
|
|
||||||
|
require_relative '../utils/list_node'
|
||||||
|
|
||||||
|
### 基于链表头现的队列 ###
|
||||||
|
class LinkedListQueue
|
||||||
|
### 获取队列的长度 ###
|
||||||
|
attr_reader :size
|
||||||
|
|
||||||
|
### 构造方法 ###
|
||||||
|
def initialize
|
||||||
|
@front = nil # 头节点 front
|
||||||
|
@rear = nil # 尾节点 rear
|
||||||
|
@size = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
### 判断队列是否为空 ###
|
||||||
|
def is_empty?
|
||||||
|
@front.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
### 入队 ###
|
||||||
|
def push(num)
|
||||||
|
# 在尾节点后添加 num
|
||||||
|
node = ListNode.new(num)
|
||||||
|
|
||||||
|
# 如果队列为空,则令头,尾节点都指向该节点
|
||||||
|
if @front.nil?
|
||||||
|
@front = node
|
||||||
|
@rear = node
|
||||||
|
# 如果队列不为空,则令该节点添加到尾节点后
|
||||||
|
else
|
||||||
|
@rear.next = node
|
||||||
|
@rear = node
|
||||||
|
end
|
||||||
|
|
||||||
|
@size += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
### 出队 ###
|
||||||
|
def pop
|
||||||
|
num = peek
|
||||||
|
# 删除头节点
|
||||||
|
@front = @front.next
|
||||||
|
@size -= 1
|
||||||
|
num
|
||||||
|
end
|
||||||
|
|
||||||
|
### 访问队首元素 ###
|
||||||
|
def peek
|
||||||
|
raise IndexError, '队列为空' if is_empty?
|
||||||
|
|
||||||
|
@front.val
|
||||||
|
end
|
||||||
|
|
||||||
|
### 将链表为 Array 并返回 ###
|
||||||
|
def to_array
|
||||||
|
queue = []
|
||||||
|
temp = @front
|
||||||
|
while temp
|
||||||
|
queue << temp.val
|
||||||
|
temp = temp.next
|
||||||
|
end
|
||||||
|
queue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
### Driver Code ###
|
||||||
|
|
||||||
|
# 初始化队列
|
||||||
|
queue = LinkedListQueue.new
|
||||||
|
|
||||||
|
# 元素如队
|
||||||
|
queue.push(1)
|
||||||
|
queue.push(3)
|
||||||
|
queue.push(2)
|
||||||
|
queue.push(5)
|
||||||
|
queue.push(4)
|
||||||
|
puts "队列 queue = #{queue.to_array}"
|
||||||
|
|
||||||
|
# 访问队首元素
|
||||||
|
peek = queue.peek
|
||||||
|
puts "队首元素 front = #{peek}"
|
||||||
|
|
||||||
|
# 元素出队
|
||||||
|
pop_front = queue.pop
|
||||||
|
puts "出队元素 pop = #{pop_front}"
|
||||||
|
puts "出队后 queue = #{queue.to_array}"
|
||||||
|
|
||||||
|
# 获取队列的长度
|
||||||
|
size = queue.size
|
||||||
|
puts "队列长度 size = #{size}"
|
||||||
|
|
||||||
|
# 判断队列是否为空
|
||||||
|
is_empty = queue.is_empty?
|
||||||
|
puts "队列是否为空 = #{is_empty}"
|
86
codes/ruby/chapter_stack_and_queue/linkedlist_stack.rb
Normal file
86
codes/ruby/chapter_stack_and_queue/linkedlist_stack.rb
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
=begin
|
||||||
|
File: linkedlist_stack.rb
|
||||||
|
Created Time: 2024-04-06
|
||||||
|
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||||
|
=end
|
||||||
|
|
||||||
|
require_relative '../utils/list_node'
|
||||||
|
|
||||||
|
### 基于链表实现的栈 ###
|
||||||
|
class LinkedListStack
|
||||||
|
attr_reader :size
|
||||||
|
|
||||||
|
### 构造方法 ###
|
||||||
|
def initialize
|
||||||
|
@size = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
### 判断栈是否为空 ###
|
||||||
|
def is_empty?
|
||||||
|
@peek.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
### 入栈 ###
|
||||||
|
def push(val)
|
||||||
|
node = ListNode.new(val)
|
||||||
|
node.next = @peek
|
||||||
|
@peek = node
|
||||||
|
@size += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
### 出栈 ###
|
||||||
|
def pop
|
||||||
|
num = peek
|
||||||
|
@peek = @peek.next
|
||||||
|
@size -= 1
|
||||||
|
num
|
||||||
|
end
|
||||||
|
|
||||||
|
### 访问栈顶元素 ###
|
||||||
|
def peek
|
||||||
|
raise IndexError, '栈为空' if is_empty?
|
||||||
|
|
||||||
|
@peek.val
|
||||||
|
end
|
||||||
|
|
||||||
|
### 将链表转化为 Array 并反回 ###
|
||||||
|
def to_array
|
||||||
|
arr = []
|
||||||
|
node = @peek
|
||||||
|
while node
|
||||||
|
arr << node.val
|
||||||
|
node = node.next
|
||||||
|
end
|
||||||
|
arr.reverse
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
### Driver Code ###
|
||||||
|
|
||||||
|
# 初始化栈
|
||||||
|
stack = LinkedListStack.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}"
|
37
codes/ruby/chapter_stack_and_queue/queue.rb
Normal file
37
codes/ruby/chapter_stack_and_queue/queue.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
=begin
|
||||||
|
File: queue.rb
|
||||||
|
Created Time: 2024-04-06
|
||||||
|
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||||
|
=end
|
||||||
|
|
||||||
|
### Driver Code ###
|
||||||
|
|
||||||
|
# 初始化队列
|
||||||
|
# Ruby 内置的队列(Thread::Queue) 没有 peek 和遍历方法,可以把 Array 当作队列来使用
|
||||||
|
queue = []
|
||||||
|
|
||||||
|
# 元素入队
|
||||||
|
queue.push(1)
|
||||||
|
queue.push(3)
|
||||||
|
queue.push(2)
|
||||||
|
queue.push(5)
|
||||||
|
queue.push(4)
|
||||||
|
puts "队列 queue = #{queue}"
|
||||||
|
|
||||||
|
# 访问队列元素
|
||||||
|
peek = queue.first
|
||||||
|
puts "队首元素 peek = #{peek}"
|
||||||
|
|
||||||
|
# 元素出队
|
||||||
|
# 清注意,由于是数组,Array#shift 方法时间复杂度为 O(n)
|
||||||
|
pop = queue.shift
|
||||||
|
puts "出队元素 pop = #{pop}"
|
||||||
|
puts "出队后 queue = #{queue}"
|
||||||
|
|
||||||
|
# 获取队列的长度
|
||||||
|
size = queue.length
|
||||||
|
puts "队列长度 size = #{size}"
|
||||||
|
|
||||||
|
# 判断队列是否为空
|
||||||
|
is_empty = queue.empty?
|
||||||
|
puts "队列是否为空 = #{is_empty}"
|
36
codes/ruby/chapter_stack_and_queue/stack.rb
Normal file
36
codes/ruby/chapter_stack_and_queue/stack.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
=begin
|
||||||
|
File: stack.rb
|
||||||
|
Created Time: 2024-04-06
|
||||||
|
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||||
|
=end
|
||||||
|
|
||||||
|
### Driver Code ###
|
||||||
|
|
||||||
|
# 初始化栈
|
||||||
|
# Ruby 没有内置的栈类,可以把 Array 当作栈来使用
|
||||||
|
stack = []
|
||||||
|
|
||||||
|
# 元素入栈
|
||||||
|
stack << 1
|
||||||
|
stack << 3
|
||||||
|
stack << 2
|
||||||
|
stack << 5
|
||||||
|
stack << 4
|
||||||
|
puts "栈 stack = #{stack}"
|
||||||
|
|
||||||
|
# 访问栈顶元素
|
||||||
|
peek = stack.last
|
||||||
|
puts "栈顶元素 peek = #{peek}"
|
||||||
|
|
||||||
|
# 元素出栈
|
||||||
|
pop = stack.pop
|
||||||
|
puts "出栈元素 pop = #{pop}"
|
||||||
|
puts "出栈后 stack = #{stack}"
|
||||||
|
|
||||||
|
# 获取栈的长度
|
||||||
|
size = stack.length
|
||||||
|
puts "栈的长度 size = #{size}"
|
||||||
|
|
||||||
|
# 判断是否为空
|
||||||
|
is_empty = stack.empty?
|
||||||
|
puts "栈是否为空 = #{is_empty}"
|
Loading…
Reference in a new issue