Bug fixes and improvements (#1318)

* Sync zh and zh-hant versions

* Update en/README.md

* Add a Q&A for chapter of introduction

* Update the callout headers

* Sync zh ang zh-hant versions

* Bug fixes
This commit is contained in:
Yudong Jin
2024-04-30 15:52:05 +08:00
committed by GitHub
parent 84b1ce2497
commit 870e3e5cb2
107 changed files with 779 additions and 87 deletions

View File

@ -12,7 +12,7 @@
vector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {
// 頂點走訪序列
vector<Vertex *> res;
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
unordered_set<Vertex *> visited = {startVet};
// 佇列用於實現 BFS
queue<Vertex *> que;

View File

@ -25,7 +25,7 @@ void dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *>
vector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {
// 頂點走訪序列
vector<Vertex *> res;
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
unordered_set<Vertex *> visited;
dfs(graph, visited, res, startVet);
return res;

View File

@ -12,7 +12,7 @@ public class graph_bfs {
List<Vertex> GraphBFS(GraphAdjList graph, Vertex startVet) {
// 頂點走訪序列
List<Vertex> res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
HashSet<Vertex> visited = [startVet];
// 佇列用於實現 BFS
Queue<Vertex> que = new();

View File

@ -26,7 +26,7 @@ public class graph_dfs {
List<Vertex> GraphDFS(GraphAdjList graph, Vertex startVet) {
// 頂點走訪序列
List<Vertex> res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
HashSet<Vertex> visited = [];
DFS(graph, visited, res, startVet);
return res;

View File

@ -14,7 +14,7 @@ List<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {
// 使用鄰接表來表示圖,以便獲取指定頂點的所有鄰接頂點
// 頂點走訪序列
List<Vertex> res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
Set<Vertex> visited = {};
visited.add(startVet);
// 佇列用於實現 BFS

View File

@ -30,7 +30,7 @@ void dfs(
List<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {
// 頂點走訪序列
List<Vertex> res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
Set<Vertex> visited = {};
dfs(graph, visited, res, startVet);
return res;

View File

@ -13,7 +13,7 @@ import (
func graphBFS(g *graphAdjList, startVet Vertex) []Vertex {
// 頂點走訪序列
res := make([]Vertex, 0)
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
visited := make(map[Vertex]struct{})
visited[startVet] = struct{}{}
// 佇列用於實現 BFS, 使用切片模擬佇列

View File

@ -28,7 +28,7 @@ func dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex
func graphDFS(g *graphAdjList, startVet Vertex) []Vertex {
// 頂點走訪序列
res := make([]Vertex, 0)
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
visited := make(map[Vertex]struct{})
dfs(g, visited, &res, startVet)
// 返回頂點走訪序列

View File

@ -9,7 +9,7 @@ func twoSumBruteForce(nums []int, target int) []int {
size := len(nums)
// 兩層迴圈,時間複雜度為 O(n^2)
for i := 0; i < size-1; i++ {
for j := i + 1; i < size; j++ {
for j := i + 1; j < size; j++ {
if nums[i]+nums[j] == target {
return []int{i, j}
}

View File

@ -15,7 +15,7 @@ public class graph_bfs {
static List<Vertex> graphBFS(GraphAdjList graph, Vertex startVet) {
// 頂點走訪序列
List<Vertex> res = new ArrayList<>();
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
Set<Vertex> visited = new HashSet<>();
visited.add(startVet);
// 佇列用於實現 BFS

View File

@ -28,7 +28,7 @@ public class graph_dfs {
static List<Vertex> graphDFS(GraphAdjList graph, Vertex startVet) {
// 頂點走訪序列
List<Vertex> res = new ArrayList<>();
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
Set<Vertex> visited = new HashSet<>();
dfs(graph, visited, res, startVet);
return res;

View File

@ -12,7 +12,7 @@ const { Vertex } = require('../modules/Vertex');
function graphBFS(graph, startVet) {
// 頂點走訪序列
const res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
const visited = new Set();
visited.add(startVet);
// 佇列用於實現 BFS

View File

@ -27,7 +27,7 @@ function dfs(graph, visited, res, vet) {
function graphDFS(graph, startVet) {
// 頂點走訪序列
const res = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
const visited = new Set();
dfs(graph, visited, res, startVet);
return res;

View File

@ -0,0 +1,63 @@
import { bold, brightRed } from 'jsr:@std/fmt/colors';
import { expandGlob } from 'jsr:@std/fs';
import { relative, resolve } from 'jsr:@std/path';
/**
* @typedef {import('jsr:@std/fs').WalkEntry} WalkEntry
* @type {WalkEntry[]}
*/
const entries = [];
for await (const entry of expandGlob(
resolve(import.meta.dirname, './chapter_*/*.js')
)) {
entries.push(entry);
}
/** @type {{ status: Promise<Deno.CommandStatus>; stderr: ReadableStream<Uint8Array>; }[]} */
const processes = [];
for (const file of entries) {
const execute = new Deno.Command('node', {
args: [relative(import.meta.dirname, file.path)],
cwd: import.meta.dirname,
stdin: 'piped',
stdout: 'piped',
stderr: 'piped',
});
const process = execute.spawn();
processes.push({ status: process.status, stderr: process.stderr });
}
const results = await Promise.all(
processes.map(async (item) => {
const status = await item.status;
return { status, stderr: item.stderr };
})
);
/** @type {ReadableStream<Uint8Array>[]} */
const errors = [];
for (const result of results) {
if (!result.status.success) {
errors.push(result.stderr);
}
}
console.log(`Tested ${entries.length} files`);
console.log(`Found exception in ${errors.length} files`);
if (errors.length) {
console.log();
for (const error of errors) {
const reader = error.getReader();
const { value } = await reader.read();
const decoder = new TextDecoder();
console.log(`${bold(brightRed('error'))}: ${decoder.decode(value)}`);
}
throw new Error('Test failed');
}

View File

@ -14,7 +14,7 @@ import java.util.*
fun graphBFS(graph: GraphAdjList, startVet: Vertex): MutableList<Vertex?> {
// 頂點走訪序列
val res = mutableListOf<Vertex?>()
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
val visited = HashSet<Vertex>()
visited.add(startVet)
// 佇列用於實現 BFS

View File

@ -31,7 +31,7 @@ fun dfs(
fun graphDFS(graph: GraphAdjList, startVet: Vertex?): MutableList<Vertex?> {
// 頂點走訪序列
val res = mutableListOf<Vertex?>()
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
val visited = HashSet<Vertex?>()
dfs(graph, visited, res, startVet)
return res

View File

@ -18,7 +18,7 @@ def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
# 使用鄰接表來表示圖,以便獲取指定頂點的所有鄰接頂點
# 頂點走訪序列
res = []
# 雜湊,用於記錄已被訪問過的頂點
# 雜湊集合,用於記錄已被訪問過的頂點
visited = set[Vertex]([start_vet])
# 佇列用於實現 BFS
que = deque[Vertex]([start_vet])

View File

@ -29,7 +29,7 @@ def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
# 使用鄰接表來表示圖,以便獲取指定頂點的所有鄰接頂點
# 頂點走訪序列
res = []
# 雜湊,用於記錄已被訪問過的頂點
# 雜湊集合,用於記錄已被訪問過的頂點
visited = set[Vertex]()
dfs(graph, visited, res, start_vet)
return res

View File

@ -18,7 +18,7 @@ class ArrayStack:
def is_empty(self) -> bool:
"""判斷堆疊是否為空"""
return self._size == 0
return self.size() == 0
def push(self, item: int):
"""入堆疊"""

View File

@ -22,7 +22,7 @@ class ArrayBinaryTree:
"""串列容量"""
return len(self._tree)
def val(self, i: int) -> int:
def val(self, i: int) -> int | None:
"""獲取索引為 i 節點的值"""
# 若索引越界,則返回 None ,代表空位
if i < 0 or i >= self.size():

View File

@ -0,0 +1,116 @@
=begin
File: graph_adjacency_list.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/vertex'
### 基於鄰接表實現的無向圖類別 ###
class GraphAdjList
attr_reader :adj_list
### 建構子 ###
def initialize(edges)
# 鄰接表key頂點value該頂點的所有鄰接頂點
@adj_list = {}
# 新增所有頂點和邊
for edge in edges
add_vertex(edge[0])
add_vertex(edge[1])
add_edge(edge[0], edge[1])
end
end
### 獲取頂點數量 ###
def size
@adj_list.length
end
### 新增邊 ###
def add_edge(vet1, vet2)
raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)
@adj_list[vet1] << vet2
@adj_list[vet2] << vet1
end
### 刪除邊 ###
def remove_edge(vet1, vet2)
raise ArgumentError if !@adj_list.include?(vet1) || !@adj_list.include?(vet2)
# 刪除邊 vet1 - vet2
@adj_list[vet1].delete(vet2)
@adj_list[vet2].delete(vet1)
end
### 新增頂點 ###
def add_vertex(vet)
return if @adj_list.include?(vet)
# 在鄰接表中新增一個新鏈結串列
@adj_list[vet] = []
end
### 刪除頂點 ###
def remove_vertex(vet)
raise ArgumentError unless @adj_list.include?(vet)
# 在鄰接表中刪除頂點 vet 對應的鏈結串列
@adj_list.delete(vet)
# 走訪其他頂點的鏈結串列,刪除所有包含 vet 的邊
for vertex in @adj_list
@adj_list[vertex.first].delete(vet) if @adj_list[vertex.first].include?(vet)
end
end
### 列印鄰接表 ###
def __print__
puts '鄰接表 ='
for vertex in @adj_list
tmp = @adj_list[vertex.first].map { |v| v.val }
puts "#{vertex.first.val}: #{tmp},"
end
end
end
### Driver Code ###
if __FILE__ == $0
# 初始化無向圖
v = vals_to_vets([1, 3, 2, 5, 4])
edges = [
[v[0], v[1]],
[v[0], v[3]],
[v[1], v[2]],
[v[2], v[3]],
[v[2], v[4]],
[v[3], v[4]],
]
graph = GraphAdjList.new(edges)
puts "\n初始化後,圖為"
graph.__print__
# 新增邊
# 頂點 12 即 v[0]v[2]
graph.add_edge(v[0], v[2])
puts "\n新增邊 1-2 後,圖為"
graph.__print__
# 刪除邊
# 頂點 13 即 v[0]v[1]
graph.remove_edge(v[0], v[1])
puts "\n刪除邊 1-3 後,圖為"
graph.__print__
# 新增頂點
v5 = Vertex.new(6)
graph.add_vertex(v5)
puts "\n新增頂點 6 後,圖為"
graph.__print__
# 刪除頂點
# 頂點 3 即 v[1]
graph.remove_vertex(v[1])
puts "\n刪除頂點 3 後,圖為"
graph.__print__
end

View File

@ -0,0 +1,116 @@
=begin
File: graph_adjacency_matrix.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/print_util'
### 基於鄰接矩陣實現的無向圖類別 ###
class GraphAdjMat
def initialize(vertices, edges)
### 建構子 ###
# 頂點串列,元素代表“頂點值”,索引代表“頂點索引”
@vertices = []
# 鄰接矩陣,行列索引對應“頂點索引”
@adj_mat = []
# 新增頂點
vertices.each { |val| add_vertex(val) }
# 新增邊
# 請注意edges 元素代表頂點索引,即對應 vertices 元素索引
edges.each { |e| add_edge(e[0], e[1]) }
end
### 獲取頂點數量 ###
def size
@vertices.length
end
### 新增頂點 ###
def add_vertex(val)
n = size
# 向頂點串列中新增新頂點的值
@vertices << val
# 在鄰接矩陣中新增一行
new_row = Array.new(n, 0)
@adj_mat << new_row
# 在鄰接矩陣中新增一列
@adj_mat.each { |row| row << 0 }
end
### 刪除頂點 ###
def remove_vertex(index)
raise IndexError if index >= size
# 在頂點串列中移除索引 index 的頂點
@vertices.delete_at(index)
# 在鄰接矩陣中刪除索引 index 的行
@adj_mat.delete_at(index)
# 在鄰接矩陣中刪除索引 index 的列
@adj_mat.each { |row| row.delete_at(index) }
end
### 新增邊 ###
def add_edge(i, j)
# 參數 i, j 對應 vertices 元素索引
# 索引越界與相等處理
if i < 0 || j < 0 || i >= size || j >= size || i == j
raise IndexError
end
# 在無向圖中,鄰接矩陣關於主對角線對稱,即滿足 (i, j) == (j, i)
@adj_mat[i][j] = 1
@adj_mat[j][i] = 1
end
### 刪除邊 ###
def remove_edge(i, j)
# 參數 i, j 對應 vertices 元素索引
# 索引越界與相等處理
if i < 0 || j < 0 || i >= size || j >= size || i == j
raise IndexError
end
@adj_mat[i][j] = 0
@adj_mat[j][i] = 0
end
### 列印鄰接矩陣 ###
def __print__
puts "頂點串列 = #{@vertices}"
puts '鄰接矩陣 ='
print_matrix(@adj_mat)
end
end
### Driver Code ###
if __FILE__ == $0
# 初始化無向圖
# 請注意edges 元素代表頂點索引,即對應 vertices 元素索引
vertices = [1, 3, 2, 5, 4]
edges = [[0, 1], [0, 3], [1, 2], [2, 3], [2, 4], [3, 4]]
graph = GraphAdjMat.new(vertices, edges)
puts "\n初始化後,圖為"
graph.__print__
# 新增邊
# 頂點 1, 2 的索引分別為 0, 2
graph.add_edge(0, 2)
puts "\n新增邊 1-2 後,圖為"
graph.__print__
# 刪除邊
# 定點 1, 3 的索引分別為 0, 1
graph.remove_edge(0, 1)
puts "\n刪除邊 1-3 後,圖為"
graph.__print__
# 新增頂點
graph.add_vertex(6)
puts "\n新增頂點 6 後,圖為"
graph.__print__
# 刪除頂點
# 頂點 3 的索引為 1
graph.remove_vertex(1)
puts "\n刪除頂點 3 後,圖為"
graph.__print__
end

View File

@ -0,0 +1,61 @@
=begin
File: graph_bfs.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require 'set'
require_relative './graph_adjacency_list'
require_relative '../utils/vertex'
### 廣度優先走訪 ###
def graph_bfs(graph, start_vet)
# 使用鄰接表來表示圖,以便獲取指定頂點的所有鄰接頂點
# 頂點走訪序列
res = []
# 雜湊集合,用於記錄已被訪問過的頂點
visited = Set.new([start_vet])
# 佇列用於實現 BFS
que = [start_vet]
# 以頂點 vet 為起點,迴圈直至訪問完所有頂點
while que.length > 0
vet = que.shift # 佇列首頂點出隊
res << vet # 記錄訪問頂點
# 走訪該頂點的所有鄰接頂點
for adj_vet in graph.adj_list[vet]
next if visited.include?(adj_vet) # 跳過已被訪問的頂點
que << adj_vet # 只入列未訪問的頂點
visited.add(adj_vet) # 標記該頂點已被訪問
end
end
# 返回頂點走訪序列
res
end
### Driver Code ###
if __FILE__ == $0
# 初始化無向圖
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
edges = [
[v[0], v[1]],
[v[0], v[3]],
[v[1], v[2]],
[v[1], v[4]],
[v[2], v[5]],
[v[3], v[4]],
[v[3], v[6]],
[v[4], v[5]],
[v[4], v[7]],
[v[5], v[8]],
[v[6], v[7]],
[v[7], v[8]],
]
graph = GraphAdjList.new(edges)
puts "\n初始化後,圖為"
graph.__print__
# 廣度優先走訪
res = graph_bfs(graph, v.first)
puts "\n廣度優先便利BFS頂點序列為"
p vets_to_vals(res)
end

View File

@ -0,0 +1,54 @@
=begin
File: graph_dfs.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require 'set'
require_relative './graph_adjacency_list'
require_relative '../utils/vertex'
### 深度優先走訪輔助函式 ###
def dfs(graph, visited, res, vet)
res << vet # 記錄訪問頂點
visited.add(vet) # 標記該頂點已被訪問
# 走訪該頂點的所有鄰接頂點
for adj_vet in graph.adj_list[vet]
next if visited.include?(adj_vet) # 跳過已被訪問的頂點
# 遞迴訪問鄰接頂點
dfs(graph, visited, res, adj_vet)
end
end
### 深度優先走訪 ###
def graph_dfs(graph, start_vet)
# 使用鄰接表來表示圖,以便獲取指定頂點的所有鄰接頂點
# 頂點走訪序列
res = []
# 雜湊集合,用於記錄已被訪問過的頂點
visited = Set.new
dfs(graph, visited, res, start_vet)
res
end
### Driver Code ###
if __FILE__ == $0
# 初始化無向圖
v = vals_to_vets([0, 1, 2, 3, 4, 5, 6])
edges = [
[v[0], v[1]],
[v[0], v[3]],
[v[1], v[2]],
[v[2], v[5]],
[v[4], v[5]],
[v[5], v[6]],
]
graph = GraphAdjList.new(edges)
puts "\n初始化後,圖為"
graph.__print__
# 深度優先走訪
res = graph_dfs(graph, v[0])
puts "\n深度優先走訪DFS頂點序列為"
p vets_to_vals(res)
end

View File

@ -0,0 +1,147 @@
=begin
File: my_heap.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative '../utils/print_util'
### 大頂堆積 ###
class MaxHeap
attr_reader :max_heap
### 建構子,根據輸入串列建堆積 ###
def initialize(nums)
# 將串列元素原封不動新增進堆積
@max_heap = nums
# 堆積化除葉節點以外的其他所有節點
parent(size - 1).downto(0) do |i|
sift_down(i)
end
end
### 獲取左子節點的索引 ###
def left(i)
2 * i + 1
end
### 獲取右子節點的索引 ###
def right(i)
2 * i + 2
end
### 獲取父節點的索引 ###
def parent(i)
(i - 1) / 2 # 向下整除
end
### 交換元素 ###
def swap(i, j)
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
end
### 獲取堆積大小 ###
def size
@max_heap.length
end
### 判斷堆積是否為空 ###
def is_empty?
size == 0
end
### 訪問堆積頂元素 ###
def peek
@max_heap[0]
end
### 元素入堆積 ###
def push(val)
# 新增節點
@max_heap << val
# 從底至頂堆積化
sift_up(size - 1)
end
### 從節點 i 開始,從底至頂堆積化 ###
def sift_up(i)
loop do
# 獲取節點 i 的父節點
p = parent(i)
# 當“越過根節點”或“節點無須修復”時,結束堆積化
break if p < 0 || @max_heap[i] <= @max_heap[p]
# 交換兩節點
swap(i, p)
# 迴圈向上堆積化
i = p
end
end
### 元素出堆積 ###
def pop
# 判空處理
raise IndexError, "堆積為空" if is_empty?
# 交換根節點與最右葉節點(交換首元素與尾元素)
swap(0, size - 1)
# 刪除節點
val = @max_heap.pop
# 從頂至底堆積化
sift_down(0)
# 返回堆積頂元素
val
end
### 從節點 i 開始,從頂至底堆積化 ###
def sift_down(i)
loop do
# 判斷節點 i, l, r 中值最大的節點,記為 ma
l, r, ma = left(i), right(i), i
ma = l if l < size && @max_heap[l] > @max_heap[ma]
ma = r if r < size && @max_heap[r] > @max_heap[ma]
# 若節點 i 最大或索引 l, r 越界,則無須繼續堆積化,跳出
break if ma == i
# 交換兩節點
swap(i, ma)
# 迴圈向下堆積化
i = ma
end
end
### 列印堆積(二元樹)###
def __print__
print_heap(@max_heap)
end
end
### Driver Code ###
if __FILE__ == $0
# 初始化大頂堆積
max_heap = MaxHeap.new([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2])
puts "\n輸入串列並建堆積後"
max_heap.__print__
# 獲取堆積頂元素
peek = max_heap.peek
puts "\n堆積頂元素為 #{peek}"
# 元素入堆積
val = 7
max_heap.push(val)
puts "\n元素 #{val} 入堆積後"
max_heap.__print__
# 堆積頂元素出堆積
peek = max_heap.pop
puts "\n堆積頂元素 #{peek} 出堆積後"
max_heap.__print__
# 獲取堆積大小
size = max_heap.size
puts "\n堆積元素數量為 #{size}"
# 判斷堆積是否為空
is_empty = max_heap.is_empty?
puts "\n堆積是否為空 #{is_empty}"
end

View File

@ -0,0 +1,64 @@
=begin
File: top_k.rb
Created Time: 2024-04-19
Author: Blue Bean (lonnnnnnner@gmail.com)
=end
require_relative "./my_heap"
### 元素入堆積 ###
def push_min_heap(heap, val)
# 元素取反
heap.push(-val)
end
### 元素出堆積 ###
def pop_min_heap(heap)
# 元素取反
-heap.pop
end
### 訪問堆積頂元素 ###
def peek_min_heap(heap)
# 元素取反
-heap.peek
end
### 取出堆積中元素 ###
def get_min_heap(heap)
# 將堆積中所有元素取反
heap.max_heap.map { |x| -x }
end
### 基於堆積查詢陣列中最大的 k 個元素 ###
def top_k_heap(nums, k)
# 初始化小頂堆積
# 請注意:我們將堆積中所有元素取反,從而用大頂堆積來模擬小頂堆積
max_heap = MaxHeap.new([])
# 將陣列的前 k 個元素入堆積
for i in 0...k
push_min_heap(max_heap, nums[i])
end
# 從第 k+1 個元素開始,保持堆積的長度為 k
for i in k...nums.length
# 若當前元素大於堆積頂元素,則將堆積頂元素出堆積、當前元素入堆積
if nums[i] > peek_min_heap(max_heap)
pop_min_heap(max_heap)
push_min_heap(max_heap, nums[i])
end
end
get_min_heap(max_heap)
end
### Driver Code ###
if __FILE__ == $0
nums = [1, 7, 6, 3, 2]
k = 3
res = top_k_heap(nums, k)
puts "最大的 #{k} 個元素為"
print_heap(res)
end

View File

@ -4,6 +4,15 @@ Created Time: 2024-03-18
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative "./tree_node"
### 列印矩陣 ###
def print_matrix(mat)
s = []
mat.each { |arr| s << " #{arr.to_s}" }
puts "[\n#{s.join(",\n")}\n]"
end
### 列印鏈結串列 ###
def print_linked_list(head)
list = []
@ -61,3 +70,11 @@ end
def print_hash_map(hmap)
hmap.entries.each { |key, value| puts "#{key} -> #{value}" }
end
### 列印堆積 ###
def print_heap(heap)
puts "堆積的陣列表示:#{heap}"
puts "堆積的樹狀表示:"
root = arr_to_tree(heap)
print_tree(root)
end

View File

@ -0,0 +1,24 @@
=begin
File: vertex.rb
Created Time: 2024-04-25
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### 頂點類別 ###
class Vertex
attr_accessor :val
def initialize(val)
@val = val
end
end
### 輸入值串列 vals ,返回頂點串列 vets ###
def vals_to_vets(vals)
Array.new(vals.length) { |i| Vertex.new(vals[i]) }
end
### 輸入頂點串列 vets, 返回值串列 vals ###
def vets_to_vals(vets)
Array.new(vets.length) { |i| vets[i].val }
end

View File

@ -15,7 +15,7 @@ use std::collections::{HashSet, VecDeque};
fn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {
// 頂點走訪序列
let mut res = vec![];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
let mut visited = HashSet::new();
visited.insert(start_vet);
// 佇列用於實現 BFS

View File

@ -31,7 +31,7 @@ fn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex
fn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {
// 頂點走訪序列
let mut res = vec![];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
let mut visited = HashSet::new();
dfs(&graph, &mut visited, &mut res, start_vet);

View File

@ -96,7 +96,7 @@ impl MaxHeap {
// 交換根節點與最右葉節點(交換首元素與尾元素)
self.swap(0, self.size() - 1);
// 刪除節點
let val = self.max_heap.remove(self.size() - 1);
let val = self.max_heap.pop().unwrap();
// 從頂至底堆積化
self.sift_down(0);
// 返回堆積頂元素

View File

@ -12,7 +12,7 @@ import utils
func graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {
//
var res: [Vertex] = []
//
//
var visited: Set<Vertex> = [startVet]
// BFS
var que: [Vertex] = [startVet]

View File

@ -26,7 +26,7 @@ func dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], v
func graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {
//
var res: [Vertex] = []
//
//
var visited: Set<Vertex> = []
dfs(graph: graph, visited: &visited, res: &res, vet: startVet)
return res

View File

@ -12,7 +12,7 @@ import { Vertex } from '../modules/Vertex';
function graphBFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {
// 頂點走訪序列
const res: Vertex[] = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
const visited: Set<Vertex> = new Set();
visited.add(startVet);
// 佇列用於實現 BFS

View File

@ -31,7 +31,7 @@ function dfs(
function graphDFS(graph: GraphAdjList, startVet: Vertex): Vertex[] {
// 頂點走訪序列
const res: Vertex[] = [];
// 雜湊,用於記錄已被訪問過的頂點
// 雜湊集合,用於記錄已被訪問過的頂點
const visited: Set<Vertex> = new Set();
dfs(graph, visited, res, startVet);
return res;