Translate all code to English (#1836)

* Review the EN heading format.

* Fix pythontutor headings.

* Fix pythontutor headings.

* bug fixes

* Fix headings in **/summary.md

* Revisit the CN-to-EN translation for Python code using Claude-4.5

* Revisit the CN-to-EN translation for Java code using Claude-4.5

* Revisit the CN-to-EN translation for Cpp code using Claude-4.5.

* Fix the dictionary.

* Fix cpp code translation for the multipart strings.

* Translate Go code to English.

* Update workflows to test EN code.

* Add EN translation for C.

* Add EN translation for CSharp.

* Add EN translation for Swift.

* Trigger the CI check.

* Revert.

* Update en/hash_map.md

* Add the EN version of Dart code.

* Add the EN version of Kotlin code.

* Add missing code files.

* Add the EN version of JavaScript code.

* Add the EN version of TypeScript code.

* Fix the workflows.

* Add the EN version of Ruby code.

* Add the EN version of Rust code.

* Update the CI check for the English version  code.

* Update Python CI check.

* Fix cmakelists for en/C code.

* Fix Ruby comments
This commit is contained in:
Yudong Jin
2025-12-31 07:44:52 +08:00
committed by GitHub
parent 45e1295241
commit 2778a6f9c7
1284 changed files with 71557 additions and 3275 deletions
@@ -0,0 +1,101 @@
// File: array_binary_tree.go
// Created Time: 2023-07-24
// Author: Reanon (793584285@qq.com)
package chapter_tree
/* Binary tree class represented by array */
type arrayBinaryTree struct {
tree []any
}
/* Constructor */
func newArrayBinaryTree(arr []any) *arrayBinaryTree {
return &arrayBinaryTree{
tree: arr,
}
}
/* List capacity */
func (abt *arrayBinaryTree) size() int {
return len(abt.tree)
}
/* Get value of node at index i */
func (abt *arrayBinaryTree) val(i int) any {
// If index out of bounds, return null to represent empty position
if i < 0 || i >= abt.size() {
return nil
}
return abt.tree[i]
}
/* Get index of left child node of node at index i */
func (abt *arrayBinaryTree) left(i int) int {
return 2*i + 1
}
/* Get index of right child node of node at index i */
func (abt *arrayBinaryTree) right(i int) int {
return 2*i + 2
}
/* Get index of parent node of node at index i */
func (abt *arrayBinaryTree) parent(i int) int {
return (i - 1) / 2
}
/* Level-order traversal */
func (abt *arrayBinaryTree) levelOrder() []any {
var res []any
// Traverse array directly
for i := 0; i < abt.size(); i++ {
if abt.val(i) != nil {
res = append(res, abt.val(i))
}
}
return res
}
/* Depth-first traversal */
func (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {
// If empty position, return
if abt.val(i) == nil {
return
}
// Preorder traversal
if order == "pre" {
*res = append(*res, abt.val(i))
}
abt.dfs(abt.left(i), order, res)
// Inorder traversal
if order == "in" {
*res = append(*res, abt.val(i))
}
abt.dfs(abt.right(i), order, res)
// Postorder traversal
if order == "post" {
*res = append(*res, abt.val(i))
}
}
/* Preorder traversal */
func (abt *arrayBinaryTree) preOrder() []any {
var res []any
abt.dfs(0, "pre", &res)
return res
}
/* Inorder traversal */
func (abt *arrayBinaryTree) inOrder() []any {
var res []any
abt.dfs(0, "in", &res)
return res
}
/* Postorder traversal */
func (abt *arrayBinaryTree) postOrder() []any {
var res []any
abt.dfs(0, "post", &res)
return res
}
@@ -0,0 +1,47 @@
// File: array_binary_tree_test.go
// Created Time: 2023-07-24
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestArrayBinaryTree(t *testing.T) {
// Initialize binary tree
// Here we use a function to generate a binary tree directly from an array
arr := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}
root := SliceToTree(arr)
fmt.Println("\nInitialize binary tree")
fmt.Println("Array representation of binary tree:")
fmt.Println(arr)
fmt.Println("Linked list representation of binary tree:")
PrintTree(root)
// Binary tree class represented by array
abt := newArrayBinaryTree(arr)
// Access node
i := 1
l := abt.left(i)
r := abt.right(i)
p := abt.parent(i)
fmt.Println("\nCurrent node index is", i, ", value is", abt.val(i))
fmt.Println("Its left child node index is", l, ", value is", abt.val(l))
fmt.Println("Its right child node index is", r, ", value is", abt.val(r))
fmt.Println("Its parent node index is", p, ", value is", abt.val(p))
// Traverse tree
res := abt.levelOrder()
fmt.Println("\nLevel-order traversal is:", res)
res = abt.preOrder()
fmt.Println("Preorder traversal is:", res)
res = abt.inOrder()
fmt.Println("Inorder traversal is:", res)
res = abt.postOrder()
fmt.Println("Postorder traversal is:", res)
}
+200
View File
@@ -0,0 +1,200 @@
// File: avl_tree.go
// Created Time: 2023-01-08
// Author: Reanon (793584285@qq.com)
package chapter_tree
import . "github.com/krahets/hello-algo/pkg"
/* AVL tree */
type aVLTree struct {
// Root node
root *TreeNode
}
func newAVLTree() *aVLTree {
return &aVLTree{root: nil}
}
/* Get node height */
func (t *aVLTree) height(node *TreeNode) int {
// Empty node height is -1, leaf node height is 0
if node != nil {
return node.Height
}
return -1
}
/* Update node height */
func (t *aVLTree) updateHeight(node *TreeNode) {
lh := t.height(node.Left)
rh := t.height(node.Right)
// Node height equals the height of the tallest subtree + 1
if lh > rh {
node.Height = lh + 1
} else {
node.Height = rh + 1
}
}
/* Get balance factor */
func (t *aVLTree) balanceFactor(node *TreeNode) int {
// Empty node balance factor is 0
if node == nil {
return 0
}
// Node balance factor = left subtree height - right subtree height
return t.height(node.Left) - t.height(node.Right)
}
/* Right rotation operation */
func (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {
child := node.Left
grandChild := child.Right
// Using child as pivot, rotate node to the right
child.Right = node
node.Left = grandChild
// Update node height
t.updateHeight(node)
t.updateHeight(child)
// Return root node of subtree after rotation
return child
}
/* Left rotation operation */
func (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {
child := node.Right
grandChild := child.Left
// Using child as pivot, rotate node to the left
child.Left = node
node.Right = grandChild
// Update node height
t.updateHeight(node)
t.updateHeight(child)
// Return root node of subtree after rotation
return child
}
/* Perform rotation operation to restore balance to this subtree */
func (t *aVLTree) rotate(node *TreeNode) *TreeNode {
// Get balance factor of node
// Go recommends short variables, here bf refers to t.balanceFactor
bf := t.balanceFactor(node)
// Left-leaning tree
if bf > 1 {
if t.balanceFactor(node.Left) >= 0 {
// Right rotation
return t.rightRotate(node)
} else {
// First left rotation then right rotation
node.Left = t.leftRotate(node.Left)
return t.rightRotate(node)
}
}
// Right-leaning tree
if bf < -1 {
if t.balanceFactor(node.Right) <= 0 {
// Left rotation
return t.leftRotate(node)
} else {
// First right rotation then left rotation
node.Right = t.rightRotate(node.Right)
return t.leftRotate(node)
}
}
// Balanced tree, no rotation needed, return directly
return node
}
/* Insert node */
func (t *aVLTree) insert(val int) {
t.root = t.insertHelper(t.root, val)
}
/* Recursively insert node (helper function) */
func (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {
if node == nil {
return NewTreeNode(val)
}
/* 1. Find insertion position and insert node */
if val < node.Val.(int) {
node.Left = t.insertHelper(node.Left, val)
} else if val > node.Val.(int) {
node.Right = t.insertHelper(node.Right, val)
} else {
// Duplicate node not inserted, return directly
return node
}
// Update node height
t.updateHeight(node)
/* 2. Perform rotation operation to restore balance to this subtree */
node = t.rotate(node)
// Return root node of subtree
return node
}
/* Remove node */
func (t *aVLTree) remove(val int) {
t.root = t.removeHelper(t.root, val)
}
/* Recursively remove node (helper function) */
func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {
if node == nil {
return nil
}
/* 1. Find node and delete */
if val < node.Val.(int) {
node.Left = t.removeHelper(node.Left, val)
} else if val > node.Val.(int) {
node.Right = t.removeHelper(node.Right, val)
} else {
if node.Left == nil || node.Right == nil {
child := node.Left
if node.Right != nil {
child = node.Right
}
if child == nil {
// Number of child nodes = 0, delete node directly and return
return nil
} else {
// Number of child nodes = 1, delete node directly
node = child
}
} else {
// Number of child nodes = 2, delete the next node in inorder traversal and replace current node with it
temp := node.Right
for temp.Left != nil {
temp = temp.Left
}
node.Right = t.removeHelper(node.Right, temp.Val.(int))
node.Val = temp.Val
}
}
// Update node height
t.updateHeight(node)
/* 2. Perform rotation operation to restore balance to this subtree */
node = t.rotate(node)
// Return root node of subtree
return node
}
/* Search node */
func (t *aVLTree) search(val int) *TreeNode {
cur := t.root
// Loop search, exit after passing leaf node
for cur != nil {
if cur.Val.(int) < val {
// Target node is in cur's right subtree
cur = cur.Right
} else if cur.Val.(int) > val {
// Target node is in cur's left subtree
cur = cur.Left
} else {
// Found target node, exit loop
break
}
}
// Return target node
return cur
}
+54
View File
@@ -0,0 +1,54 @@
// File: avl_tree_test.go
// Created Time: 2023-01-08
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestAVLTree(t *testing.T) {
/* Please pay attention to how the AVL tree maintains balance after inserting nodes */
tree := newAVLTree()
/* Insert node */
// Delete nodes
testInsert(tree, 1)
testInsert(tree, 2)
testInsert(tree, 3)
testInsert(tree, 4)
testInsert(tree, 5)
testInsert(tree, 8)
testInsert(tree, 7)
testInsert(tree, 9)
testInsert(tree, 10)
testInsert(tree, 6)
/* Please pay attention to how the AVL tree maintains balance after deleting nodes */
testInsert(tree, 7)
/* Remove node */
// Delete node with degree 1
testRemove(tree, 8) // Delete node with degree 2
testRemove(tree, 5) // Remove node with degree 1
testRemove(tree, 4) // Remove node with degree 2
/* Search node */
node := tree.search(7)
fmt.Printf("\nFound node object is %#v, node value = %d \n", node, node.Val)
}
func testInsert(tree *aVLTree, val int) {
tree.insert(val)
fmt.Printf("\nAfter inserting node %d, AVL tree is \n", val)
PrintTree(tree.root)
}
func testRemove(tree *aVLTree, val int) {
tree.remove(val)
fmt.Printf("\nAfter removing node %d, AVL tree is \n", val)
PrintTree(tree.root)
}
@@ -0,0 +1,142 @@
// File: binary_search_tree.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
. "github.com/krahets/hello-algo/pkg"
)
type binarySearchTree struct {
root *TreeNode
}
func newBinarySearchTree() *binarySearchTree {
bst := &binarySearchTree{}
// Initialize empty tree
bst.root = nil
return bst
}
/* Get root node */
func (bst *binarySearchTree) getRoot() *TreeNode {
return bst.root
}
/* Search node */
func (bst *binarySearchTree) search(num int) *TreeNode {
node := bst.root
// Loop search, exit after passing leaf node
for node != nil {
if node.Val.(int) < num {
// Target node is in cur's right subtree
node = node.Right
} else if node.Val.(int) > num {
// Target node is in cur's left subtree
node = node.Left
} else {
// Found target node, exit loop
break
}
}
// Return target node
return node
}
/* Insert node */
func (bst *binarySearchTree) insert(num int) {
cur := bst.root
// If tree is empty, initialize root node
if cur == nil {
bst.root = NewTreeNode(num)
return
}
// Node position before the node to be inserted
var pre *TreeNode = nil
// Loop search, exit after passing leaf node
for cur != nil {
if cur.Val == num {
return
}
pre = cur
if cur.Val.(int) < num {
cur = cur.Right
} else {
cur = cur.Left
}
}
// Insert node
node := NewTreeNode(num)
if pre.Val.(int) < num {
pre.Right = node
} else {
pre.Left = node
}
}
/* Remove node */
func (bst *binarySearchTree) remove(num int) {
cur := bst.root
// If tree is empty, return directly
if cur == nil {
return
}
// Node position before the node to be removed
var pre *TreeNode = nil
// Loop search, exit after passing leaf node
for cur != nil {
if cur.Val == num {
break
}
pre = cur
if cur.Val.(int) < num {
// Node to be removed is in right subtree
cur = cur.Right
} else {
// Node to be removed is in left subtree
cur = cur.Left
}
}
// If no node to delete, return directly
if cur == nil {
return
}
// Number of child nodes is 0 or 1
if cur.Left == nil || cur.Right == nil {
var child *TreeNode = nil
// Get child node of node to be removed
if cur.Left != nil {
child = cur.Left
} else {
child = cur.Right
}
// Delete node cur
if cur != bst.root {
if pre.Left == cur {
pre.Left = child
} else {
pre.Right = child
}
} else {
// If deleted node is root node, reassign root node
bst.root = child
}
// Number of child nodes is 2
} else {
// Get next node of node cur to be removed in in-order traversal
tmp := cur.Right
for tmp.Left != nil {
tmp = tmp.Left
}
// Recursively delete node tmp
bst.remove(tmp.Val.(int))
// Replace cur with tmp
cur.Val = tmp.Val
}
}
/* Print binary search tree */
func (bst *binarySearchTree) print() {
PrintTree(bst.root)
}
@@ -0,0 +1,45 @@
// File: binary_search_tree_test.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
)
func TestBinarySearchTree(t *testing.T) {
bst := newBinarySearchTree()
nums := []int{8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15}
// Please note that different insertion orders will generate different binary trees, this sequence can generate a perfect binary tree
for _, num := range nums {
bst.insert(num)
}
fmt.Println("\nInitialized binary tree is:")
bst.print()
// Get root node
node := bst.getRoot()
fmt.Println("\nRoot node of binary tree is:", node.Val)
// Search node
node = bst.search(7)
fmt.Println("Found node object is", node, ", node value =", node.Val)
// Insert node
bst.insert(16)
fmt.Println("\nAfter inserting node 16, binary tree is:")
bst.print()
// Remove node
bst.remove(1)
fmt.Println("\nAfter removing node 1, binary tree is:")
bst.print()
bst.remove(2)
fmt.Println("\nAfter removing node 2, binary tree is:")
bst.print()
bst.remove(4)
fmt.Println("\nAfter removing node 4, binary tree is:")
bst.print()
}
@@ -0,0 +1,35 @@
// File: binary_tree_bfs.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"container/list"
. "github.com/krahets/hello-algo/pkg"
)
/* Level-order traversal */
func levelOrder(root *TreeNode) []any {
// Initialize queue, add root node
queue := list.New()
queue.PushBack(root)
// Initialize a slice to save traversal sequence
nums := make([]any, 0)
for queue.Len() > 0 {
// Dequeue
node := queue.Remove(queue.Front()).(*TreeNode)
// Save node value
nums = append(nums, node.Val)
if node.Left != nil {
// Left child node enqueue
queue.PushBack(node.Left)
}
if node.Right != nil {
// Right child node enqueue
queue.PushBack(node.Right)
}
}
return nums
}
@@ -0,0 +1,24 @@
// File: binary_tree_bfs_test.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestLevelOrder(t *testing.T) {
/* Initialize binary tree */
// Here we use a function to generate a binary tree directly from an array
root := SliceToTree([]any{1, 2, 3, 4, 5, 6, 7})
fmt.Println("\nInitialize binary tree: ")
PrintTree(root)
// Level-order traversal
nums := levelOrder(root)
fmt.Println("\nLevel-order traversal node print sequence =", nums)
}
@@ -0,0 +1,44 @@
// File: binary_tree_dfs.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
. "github.com/krahets/hello-algo/pkg"
)
var nums []any
/* Preorder traversal */
func preOrder(node *TreeNode) {
if node == nil {
return
}
// Visit priority: root node -> left subtree -> right subtree
nums = append(nums, node.Val)
preOrder(node.Left)
preOrder(node.Right)
}
/* Inorder traversal */
func inOrder(node *TreeNode) {
if node == nil {
return
}
// Visit priority: left subtree -> root node -> right subtree
inOrder(node.Left)
nums = append(nums, node.Val)
inOrder(node.Right)
}
/* Postorder traversal */
func postOrder(node *TreeNode) {
if node == nil {
return
}
// Visit priority: left subtree -> right subtree -> root node
postOrder(node.Left)
postOrder(node.Right)
nums = append(nums, node.Val)
}
@@ -0,0 +1,35 @@
// File: binary_tree_dfs_test.go
// Created Time: 2022-11-26
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestPreInPostOrderTraversal(t *testing.T) {
/* Initialize binary tree */
// Here we use a function to generate a binary tree directly from an array
root := SliceToTree([]any{1, 2, 3, 4, 5, 6, 7})
fmt.Println("\nInitialize binary tree: ")
PrintTree(root)
// Preorder traversal
nums = nil
preOrder(root)
fmt.Println("\nPre-order traversal node print sequence =", nums)
// Inorder traversal
nums = nil
inOrder(root)
fmt.Println("\nIn-order traversal node print sequence =", nums)
// Postorder traversal
nums = nil
postOrder(root)
fmt.Println("\nPost-order traversal node print sequence =", nums)
}
@@ -0,0 +1,41 @@
// File: binary_tree_test.go
// Created Time: 2022-11-25
// Author: Reanon (793584285@qq.com)
package chapter_tree
import (
"fmt"
"testing"
. "github.com/krahets/hello-algo/pkg"
)
func TestBinaryTree(t *testing.T) {
/* Initialize binary tree */
// Initialize nodes
n1 := NewTreeNode(1)
n2 := NewTreeNode(2)
n3 := NewTreeNode(3)
n4 := NewTreeNode(4)
n5 := NewTreeNode(5)
// Build references (pointers) between nodes
n1.Left = n2
n1.Right = n3
n2.Left = n4
n2.Right = n5
fmt.Println("Initialize binary tree")
PrintTree(n1)
/* Insert node P between n1 -> n2 */
// Insert node
p := NewTreeNode(0)
n1.Left = p
p.Left = n2
fmt.Println("After inserting node P")
PrintTree(n1)
// Remove node
n1.Left = n2
fmt.Println("After removing node P")
PrintTree(n1)
}