Skip to content

Commit 2dbe6c1

Browse files
committed
Add tree algorithms
1 parent 5be1472 commit 2dbe6c1

File tree

5 files changed

+187
-1
lines changed

5 files changed

+187
-1
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Tìm kiếm theo chiều rộng (BFS)
2+
3+
Tìm kiếm theo chiều rộng là một thuật toán duyệt hoặc tìm kiếm trên cấu trúc cây hoặc đồ thị.Thuật toán bắt đầu từ đỉnh gốc và lần lượt nhìn các đỉnh kề với đỉnh gốc. Sau đó, với mỗi đỉnh trong số đó, thuật toán lại lần lượt nhìn trước các đỉnh kề với nó mà chưa được quan sát trước đó và lặp lại.
4+
5+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif)
6+
7+
## Mã giả
8+
* Input : nút gốc trong cây BST
9+
* Output : các nút trong BST đã được truy cập theo thứ tự đầu tiên theo chiều rộng
10+
11+
```text
12+
BFS(root)
13+
q ← queue
14+
while root != ø
15+
yield root.value
16+
if root.left != ø
17+
q.enqueue(root.left)
18+
end if
19+
if root.right != ø
20+
q.enqueue(root.right)
21+
end if
22+
if !q.isEmpty()
23+
root ← q.dequeue()
24+
else
25+
root ← ø
26+
end if
27+
end while
28+
end BFS
29+
```
30+
31+
Diễn giải :
32+
1. Chèn đỉnh gốc vào hàng đợi (đang hướng tới)
33+
2. Lấy ra đỉnh đầu tiên trong hàng đợi và quan sát nó
34+
- Nếu đỉnh này là đỉnh đích, dừng quá trình tìm kiếm và trả về kết quả.
35+
- Nếu không phải thì chèn tất cả các đỉnh kề với đỉnh vừa thăm nhưng chưa được quan sát trước đó vào hàng đợi.
36+
3. Nếu hàng đợi là rỗng, thì tất cả các đỉnh có thể đến được đều đã được quan sát – dừng việc tìm kiếm và trả về "không thấy".
37+
4. Nếu hàng đợi không rỗng thì quay về bước 2.
38+
39+
## References
40+
41+
- [Wikipedia](https://en.wikipedia.org/wiki/Breadth-first_search)
42+
- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/)
43+
- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import Queue from '../../../data-structures/queue/Queue';
2+
3+
/**
4+
* @typedef {Object} Callbacks
5+
* @property {function(node: BinaryTreeNode, child: BinaryTreeNode): boolean} allowTraversal -
6+
* Xác định xem BFS có nên truyền từ nút đến nút con của nó hay không.
7+
* @property {function(node: BinaryTreeNode)} enterNode - Được gọi khi BFS đi vào nút.
8+
* @property {function(node: BinaryTreeNode)} leaveNode - Được gọi khi BFS rời khỏi nút..
9+
*/
10+
11+
/**
12+
* @param {Callbacks} [callbacks]
13+
* @returns {Callbacks}
14+
*/
15+
function initCallbacks(callbacks = {}) {
16+
const initiatedCallback = callbacks;
17+
18+
const stubCallback = () => { };
19+
const defaultAllowTraversal = () => true;
20+
21+
initiatedCallback.allowTraversal = callbacks.allowTraversal || defaultAllowTraversal;
22+
initiatedCallback.enterNode = callbacks.enterNode || stubCallback;
23+
initiatedCallback.leaveNode = callbacks.leaveNode || stubCallback;
24+
25+
return initiatedCallback;
26+
}
27+
28+
/**
29+
* @param {BinaryTreeNode} rootNode
30+
* @param {Callbacks} [originalCallbacks]
31+
*/
32+
export default function breadthFirstSearch(rootNode, originalCallbacks) {
33+
const callbacks = initCallbacks(originalCallbacks);
34+
const nodeQueue = new Queue();
35+
36+
// Khởi tạo hàng đợi.
37+
nodeQueue.enqueue(rootNode);
38+
39+
while (!nodeQueue.isEmpty()) {
40+
const currentNode = nodeQueue.dequeue();
41+
42+
callbacks.enterNode(currentNode);
43+
44+
// Thêm tất cả các phần tử con vào hàng đợi để duyệt trong tương lai.
45+
46+
// Duyệt nhánh trái.
47+
if (currentNode.left && callbacks.allowTraversal(currentNode, currentNode.left)) {
48+
nodeQueue.enqueue(currentNode.left);
49+
}
50+
51+
// Duyệt nhánh phải.
52+
if (currentNode.right && callbacks.allowTraversal(currentNode, currentNode.right)) {
53+
nodeQueue.enqueue(currentNode.right);
54+
}
55+
56+
callbacks.leaveNode(currentNode);
57+
}
58+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Tìm kiếm theo chiều sâu (DFS)
2+
3+
Tìm kiếm ưu tiên chiều sâu hay tìm kiếm theo chiều sâu là một thuật toán duyệt hoặc tìm kiếm trên cấu trúc cây hoặc đồ thị. Thuật toán bắt đầu tại gốc (hoặc chọn một đỉnh nào đó coi như gốc) và khám phá xa nhất có thể theo mỗi nhánh.
4+
5+
![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif)
6+
7+
## Liên kết
8+
9+
- [Wikipedia](https://en.wikipedia.org/wiki/Depth-first_search)
10+
- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/)
11+
- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @typedef {Object} TraversalCallbacks
3+
*
4+
* @property {function(node: BinaryTreeNode, child: BinaryTreeNode): boolean} allowTraversal
5+
* - Xác định xem DFS có nên truyền từ nút đến nút con của nó hay không.
6+
*
7+
* @property {function(node: BinaryTreeNode)} enterNode - Được gọi khi DFS đi vào nút..
8+
*
9+
* @property {function(node: BinaryTreeNode)} leaveNode - Được gọi khi DFS ra khỏi nút.
10+
*/
11+
12+
/**
13+
* Mở rộng các lệnh duyệt callback bị thiếu và callback mặc định.
14+
*
15+
* @param {TraversalCallbacks} [callbacks] - Đối tượng chứa lệnh duyệt callback.
16+
* @returns {TraversalCallbacks} - Duyệt callbacks mở rộng với callbacks.
17+
*/
18+
function initCallbacks(callbacks = {}) {
19+
// Khởi tạo đối tượng callback rỗng.
20+
const initiatedCallbacks = {};
21+
22+
// Callback rỗng nghĩa là ta sẽ dùng trong trường hợp không được cung cấp hàm callback.
23+
const stubCallback = () => { };
24+
// Mặc định ta sẽ duyệt tất cả node trong trường hợp không được cung cấp callback.
25+
const defaultAllowTraversalCallback = () => true;
26+
27+
// Sao chép callback gốc cho đối tượng initiatedCallbacks hoặc sử dụng callback mặc định
28+
initiatedCallbacks.allowTraversal = callbacks.allowTraversal || defaultAllowTraversalCallback;
29+
initiatedCallbacks.enterNode = callbacks.enterNode || stubCallback;
30+
initiatedCallbacks.leaveNode = callbacks.leaveNode || stubCallback;
31+
32+
// Trả về danh sách quá trình callback.
33+
return initiatedCallbacks;
34+
}
35+
36+
/**
37+
* Duyệt đệ quy DFS cho cây nhị phân.
38+
*
39+
* @param {BinaryTreeNode} node - nút của cây nhị phân mà ta muốn bắt đầu.
40+
* @param {TraversalCallbacks} callbacks - đối tượng chứa hàm duyệt callback.
41+
*/
42+
export function depthFirstSearchRecursive(node, callbacks) {
43+
// Gọi callback "enterNode" để thông báo rằng nút sẽ được duyệt.
44+
callbacks.enterNode(node);
45+
46+
// Duyệt nhánh bên trái trong trường hợp nút trái cho phép.
47+
if (node.left && callbacks.allowTraversal(node, node.left)) {
48+
depthFirstSearchRecursive(node.left, callbacks);
49+
}
50+
51+
// Duyệt nhánh bên phải trong trường hợp nút phải cho phép.
52+
if (node.right && callbacks.allowTraversal(node, node.right)) {
53+
depthFirstSearchRecursive(node.right, callbacks);
54+
}
55+
56+
// Gọi callback "leaveNode" để thông báo việc duyệt nút hiện tại
57+
// và con của nút đã hoàn tất.
58+
callbacks.leaveNode(node);
59+
}
60+
61+
/**
62+
* Duyệt DFS với rootNode
63+
* Với tất cả bước duyệt gọi callback "allowTravel", "enterNode" và "leaveNode".
64+
* Xem kiểu TraversalCallback định nghĩa chi tiết hơn về dạng đối tượng callback.
65+
* @param {BinaryTreeNode} rootNode - Nút mà ta bắt đầu duyêt.
66+
* @param {TraversalCallbacks} [callbacks] - Duyệt callbacks.
67+
*/
68+
export default function depthFirstSearch(rootNode, callbacks) {
69+
// Trong trường hợp hàm callback không được cung cấp ta sẽ sử dụng hàm mặc đinh.
70+
const processedCallbacks = initCallbacks(callbacks);
71+
72+
// Giờ, khi ta cần tất cả callback cần thiết, ta sẽ duyệt đệ quy.
73+
depthFirstSearchRecursive(rootNode, processedCallbacks);
74+
}

src/data-structures/tree/red-black-tree/RedBlackTree.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import BinarySearchTree from '../binary-search-tree/BinarySearchTree';
22

3-
// Màu có thể của cây đỏ đen.
3+
// Màu của cây đỏ đen.
44
const RED_BLACK_TREE_COLORS = {
55
red: 'red',
66
black: 'black',

0 commit comments

Comments
 (0)