mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-23 00:37:13 +00:00
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:
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user