Skip to content

Commit 575bcf5

Browse files
authored
feat(go/tree): support array binary tree (#655)
1 parent 027bdd6 commit 575bcf5

15 files changed

Lines changed: 223 additions & 78 deletions

codes/go/chapter_backtracking/preorder_traversal_i_compact.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func preOrderI(root *TreeNode, res *[]*TreeNode) {
1313
if root == nil {
1414
return
1515
}
16-
if int(root.Val) == 7 {
16+
if (root.Val).(int) == 7 {
1717
// 记录解
1818
*res = append(*res, root)
1919
}

codes/go/chapter_backtracking/preorder_traversal_ii_compact.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func preOrderII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {
1515
}
1616
// 尝试
1717
*path = append(*path, root)
18-
if int(root.Val) == 7 {
18+
if root.Val.(int) == 7 {
1919
// 记录解
2020
*res = append(*res, *path)
2121
}

codes/go/chapter_backtracking/preorder_traversal_iii_compact.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func preOrderIII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {
1616
}
1717
// 尝试
1818
*path = append(*path, root)
19-
if int(root.Val) == 7 {
19+
if root.Val.(int) == 7 {
2020
// 记录解
2121
*res = append(*res, *path)
2222
*path = (*path)[:len(*path)-1]

codes/go/chapter_backtracking/preorder_traversal_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
func TestPreorderTraversalICompact(t *testing.T) {
1515
/* 初始化二叉树 */
16-
root := ArrToTree([]any{1, 7, 3, 4, 5, 6, 7})
16+
root := SliceToTree([]any{1, 7, 3, 4, 5, 6, 7})
1717
fmt.Println("\n初始化二叉树")
1818
PrintTree(root)
1919

@@ -30,7 +30,7 @@ func TestPreorderTraversalICompact(t *testing.T) {
3030

3131
func TestPreorderTraversalIICompact(t *testing.T) {
3232
/* 初始化二叉树 */
33-
root := ArrToTree([]any{1, 7, 3, 4, 5, 6, 7})
33+
root := SliceToTree([]any{1, 7, 3, 4, 5, 6, 7})
3434
fmt.Println("\n初始化二叉树")
3535
PrintTree(root)
3636

@@ -50,7 +50,7 @@ func TestPreorderTraversalIICompact(t *testing.T) {
5050

5151
func TestPreorderTraversalIIICompact(t *testing.T) {
5252
/* 初始化二叉树 */
53-
root := ArrToTree([]any{1, 7, 3, 4, 5, 6, 7})
53+
root := SliceToTree([]any{1, 7, 3, 4, 5, 6, 7})
5454
fmt.Println("\n初始化二叉树")
5555
PrintTree(root)
5656

@@ -70,7 +70,7 @@ func TestPreorderTraversalIIICompact(t *testing.T) {
7070

7171
func TestPreorderTraversalIIITemplate(t *testing.T) {
7272
/* 初始化二叉树 */
73-
root := ArrToTree([]any{1, 7, 3, 4, 5, 6, 7})
73+
root := SliceToTree([]any{1, 7, 3, 4, 5, 6, 7})
7474
fmt.Println("\n初始化二叉树")
7575
PrintTree(root)
7676

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// File: array_binary_tree.go
2+
// Created Time: 2023-07-24
3+
// Author: Reanon (793584285@qq.com)
4+
5+
package chapter_tree
6+
7+
/* 数组表示下的二叉树类 */
8+
type arrayBinaryTree struct {
9+
tree []any
10+
}
11+
12+
/* 构造方法 */
13+
func newArrayBinaryTree(arr []any) *arrayBinaryTree {
14+
return &arrayBinaryTree{
15+
tree: arr,
16+
}
17+
}
18+
19+
/* 节点数量 */
20+
func (abt *arrayBinaryTree) size() int {
21+
return len(abt.tree)
22+
}
23+
24+
/* 获取索引为 i 节点的值 */
25+
func (abt *arrayBinaryTree) val(i int) any {
26+
// 若索引越界,则返回 null ,代表空位
27+
if i < 0 || i >= abt.size() {
28+
return nil
29+
}
30+
return abt.tree[i]
31+
}
32+
33+
/* 获取索引为 i 节点的左子节点的索引 */
34+
func (abt *arrayBinaryTree) left(i int) int {
35+
return 2*i + 1
36+
}
37+
38+
/* 获取索引为 i 节点的右子节点的索引 */
39+
func (abt *arrayBinaryTree) right(i int) int {
40+
return 2*i + 2
41+
}
42+
43+
/* 获取索引为 i 节点的父节点的索引 */
44+
func (abt *arrayBinaryTree) parent(i int) int {
45+
return (i - 1) / 2
46+
}
47+
48+
/* 层序遍历 */
49+
func (abt *arrayBinaryTree) levelOrder() []any {
50+
var res []any
51+
// 直接遍历数组
52+
for i := 0; i < abt.size(); i++ {
53+
if abt.val(i) != nil {
54+
res = append(res, abt.val(i))
55+
}
56+
}
57+
return res
58+
}
59+
60+
/* 深度优先遍历 */
61+
func (abt *arrayBinaryTree) dfs(i int, order string, res *[]any) {
62+
// 若为空位,则返回
63+
if abt.val(i) == nil {
64+
return
65+
}
66+
// 前序遍历
67+
if order == "pre" {
68+
*res = append(*res, abt.val(i))
69+
}
70+
abt.dfs(abt.left(i), order, res)
71+
// 中序遍历
72+
if order == "in" {
73+
*res = append(*res, abt.val(i))
74+
}
75+
abt.dfs(abt.right(i), order, res)
76+
// 后序遍历
77+
if order == "post" {
78+
*res = append(*res, abt.val(i))
79+
}
80+
}
81+
82+
/* 前序遍历 */
83+
func (abt *arrayBinaryTree) preOrder() []any {
84+
var res []any
85+
abt.dfs(0, "pre", &res)
86+
return res
87+
}
88+
89+
/* 中序遍历 */
90+
func (abt *arrayBinaryTree) inOrder() []any {
91+
var res []any
92+
abt.dfs(0, "in", &res)
93+
return res
94+
}
95+
96+
/* 后序遍历 */
97+
func (abt *arrayBinaryTree) postOrder() []any {
98+
var res []any
99+
abt.dfs(0, "post", &res)
100+
return res
101+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// File: array_binary_tree_test.go
2+
// Created Time: 2023-07-24
3+
// Author: Reanon (793584285@qq.com)
4+
5+
package chapter_tree
6+
7+
import (
8+
"fmt"
9+
"testing"
10+
11+
. "github.com/krahets/hello-algo/pkg"
12+
)
13+
14+
func TestArrayBinaryTree(t *testing.T) {
15+
// 初始化二叉树
16+
// 这里借助了一个从数组直接生成二叉树的函数
17+
arr := []any{1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15}
18+
root := SliceToTree(arr)
19+
fmt.Println("\n初始化二叉树")
20+
fmt.Println("二叉树的数组表示:")
21+
fmt.Println(arr)
22+
fmt.Println("二叉树的链表表示:")
23+
PrintTree(root)
24+
25+
// 数组表示下的二叉树类
26+
abt := newArrayBinaryTree(arr)
27+
28+
// 访问节点
29+
i := 1
30+
l := abt.left(i)
31+
r := abt.right(i)
32+
p := abt.parent(i)
33+
fmt.Println("\n当前节点的索引为", i, ",值为", abt.val(i))
34+
fmt.Println("其左子节点的索引为", l, ",值为", abt.val(l))
35+
fmt.Println("其右子节点的索引为", r, ",值为", abt.val(r))
36+
fmt.Println("其父节点的索引为", p, ",值为", abt.val(p))
37+
38+
// 遍历树
39+
res := abt.levelOrder()
40+
fmt.Println("\n层序遍历为:", res)
41+
res = abt.preOrder()
42+
fmt.Println("前序遍历为:", res)
43+
res = abt.inOrder()
44+
fmt.Println("中序遍历为:", res)
45+
res = abt.postOrder()
46+
fmt.Println("后序遍历为:", res)
47+
}

codes/go/chapter_tree/avl_tree.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ func (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {
117117
return NewTreeNode(val)
118118
}
119119
/* 1. 查找插入位置,并插入节点 */
120-
if val < node.Val {
120+
if val < node.Val.(int) {
121121
node.Left = t.insertHelper(node.Left, val)
122-
} else if val > node.Val {
122+
} else if val > node.Val.(int) {
123123
node.Right = t.insertHelper(node.Right, val)
124124
} else {
125125
// 重复节点不插入,直接返回
@@ -144,9 +144,9 @@ func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {
144144
return nil
145145
}
146146
/* 1. 查找节点,并删除之 */
147-
if val < node.Val {
147+
if val < node.Val.(int) {
148148
node.Left = t.removeHelper(node.Left, val)
149-
} else if val > node.Val {
149+
} else if val > node.Val.(int) {
150150
node.Right = t.removeHelper(node.Right, val)
151151
} else {
152152
if node.Left == nil || node.Right == nil {
@@ -167,7 +167,7 @@ func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {
167167
for temp.Left != nil {
168168
temp = temp.Left
169169
}
170-
node.Right = t.removeHelper(node.Right, temp.Val)
170+
node.Right = t.removeHelper(node.Right, temp.Val.(int))
171171
node.Val = temp.Val
172172
}
173173
}
@@ -184,10 +184,10 @@ func (t *aVLTree) search(val int) *TreeNode {
184184
cur := t.root
185185
// 循环查找,越过叶节点后跳出
186186
for cur != nil {
187-
if cur.Val < val {
187+
if cur.Val.(int) < val {
188188
// 目标节点在 cur 的右子树中
189189
cur = cur.Right
190-
} else if cur.Val > val {
190+
} else if cur.Val.(int) > val {
191191
// 目标节点在 cur 的左子树中
192192
cur = cur.Left
193193
} else {

codes/go/chapter_tree/binary_search_tree.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ func (bst *binarySearchTree) search(num int) *TreeNode {
4747
node := bst.root
4848
// 循环查找,越过叶节点后跳出
4949
for node != nil {
50-
if node.Val < num {
50+
if node.Val.(int) < num {
5151
// 目标节点在 cur 的右子树中
5252
node = node.Right
53-
} else if node.Val > num {
53+
} else if node.Val.(int) > num {
5454
// 目标节点在 cur 的左子树中
5555
node = node.Left
5656
} else {
@@ -77,15 +77,15 @@ func (bst *binarySearchTree) insert(num int) {
7777
return
7878
}
7979
pre = cur
80-
if cur.Val < num {
80+
if cur.Val.(int) < num {
8181
cur = cur.Right
8282
} else {
8383
cur = cur.Left
8484
}
8585
}
8686
// 插入节点
8787
node := NewTreeNode(num)
88-
if pre.Val < num {
88+
if pre.Val.(int) < num {
8989
pre.Right = node
9090
} else {
9191
pre.Left = node
@@ -107,7 +107,7 @@ func (bst *binarySearchTree) remove(num int) {
107107
break
108108
}
109109
pre = cur
110-
if cur.Val < num {
110+
if cur.Val.(int) < num {
111111
// 待删除节点在右子树中
112112
cur = cur.Right
113113
} else {
@@ -147,7 +147,7 @@ func (bst *binarySearchTree) remove(num int) {
147147
tmp = tmp.Left
148148
}
149149
// 递归删除节点 tmp
150-
bst.remove(tmp.Val)
150+
bst.remove(tmp.Val.(int))
151151
// 用 tmp 覆盖 cur
152152
cur.Val = tmp.Val
153153
}

codes/go/chapter_tree/binary_tree_bfs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
)
1212

1313
/* 层序遍历 */
14-
func levelOrder(root *TreeNode) []int {
14+
func levelOrder(root *TreeNode) []any {
1515
// 初始化队列,加入根节点
1616
queue := list.New()
1717
queue.PushBack(root)
1818
// 初始化一个切片,用于保存遍历序列
19-
nums := make([]int, 0)
19+
nums := make([]any, 0)
2020
for queue.Len() > 0 {
2121
// 队列出队
2222
node := queue.Remove(queue.Front()).(*TreeNode)

codes/go/chapter_tree/binary_tree_bfs_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
func TestLevelOrder(t *testing.T) {
1515
/* 初始化二叉树 */
1616
// 这里借助了一个从数组直接生成二叉树的函数
17-
root := ArrToTree([]any{1, 2, 3, 4, 5, 6, 7})
17+
root := SliceToTree([]any{1, 2, 3, 4, 5, 6, 7})
1818
fmt.Println("\n初始化二叉树: ")
1919
PrintTree(root)
2020

0 commit comments

Comments
 (0)