Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 244bc97

Browse files
author
hufeng
committed
添加binarytree测试
1 parent 0a8d0cf commit 244bc97

File tree

3 files changed

+317
-0
lines changed

3 files changed

+317
-0
lines changed

‎data_structure/binarytree.go

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
package data_structure
2+
3+
import "fmt"
4+
5+
type TreeNode struct {
6+
Val int
7+
Left *TreeNode
8+
Right *TreeNode
9+
}
10+
11+
// 前序递归遍历
12+
func preorderTraversalRecursion(root *TreeNode) {
13+
if root == nil {
14+
return
15+
}
16+
// 先访问根再访问左右
17+
fmt.Printf("%v ", root.Val)
18+
preorderTraversalRecursion(root.Left)
19+
preorderTraversalRecursion(root.Right)
20+
}
21+
22+
// 前序非递归遍历
23+
func preorderTraversalNotRecursion(root *TreeNode) []int {
24+
// 非递归
25+
if root == nil {
26+
return nil
27+
}
28+
result := make([]int, 0)
29+
stack := make([]*TreeNode, 0)
30+
31+
for root != nil || len(stack) != 0 {
32+
for root != nil {
33+
// 前序遍历,所以先保存结果
34+
result = append(result, root.Val)
35+
stack = append(stack, root)
36+
root = root.Left
37+
}
38+
// pop
39+
node := stack[len(stack)-1]
40+
stack = stack[:len(stack)-1]
41+
root = node.Right
42+
}
43+
44+
return result
45+
}
46+
47+
// 中序非递归遍历
48+
func inorderTraversalNotRecursion(root *TreeNode) []int {
49+
result := make([]int, 0)
50+
if root == nil {
51+
return result
52+
}
53+
stack := make([]*TreeNode, 0)
54+
for len(stack) > 0 || root != nil {
55+
for root != nil {
56+
stack = append(stack, root)
57+
root = root.Left // 一直向左
58+
}
59+
// 弹出
60+
val := stack[len(stack)-1]
61+
stack = stack[:len(stack)-1]
62+
result = append(result, val.Val)
63+
root = val.Right
64+
}
65+
66+
return result
67+
}
68+
69+
// 后序非递归遍历
70+
func postorderTraversalNotRecursion(root *TreeNode) []int {
71+
// 通过lastVisit标识右子节点是否已经弹出
72+
if root == nil {
73+
return nil
74+
}
75+
result := make([]int, 0)
76+
stack := make([]*TreeNode, 0)
77+
var lastVisit *TreeNode
78+
for root != nil || len(stack) != 0 {
79+
for root != nil {
80+
stack = append(stack, root)
81+
root = root.Left
82+
}
83+
// 这里先看看,先不弹出
84+
node := stack[len(stack)-1]
85+
// 根节点必须在右节点弹出之后,再弹出
86+
if node.Right == nil || node.Right == lastVisit {
87+
stack = stack[:len(stack)-1] // pop
88+
result = append(result, node.Val)
89+
// 标记当前这个节点已经弹出过
90+
lastVisit = node
91+
} else {
92+
root = node.Right
93+
}
94+
}
95+
96+
return result
97+
}
98+
99+
// DFS 深度搜索-从上到下
100+
func preorderTraversalDFS(root *TreeNode) []int {
101+
result := make([]int, 0)
102+
dfs(root, &result)
103+
104+
return result
105+
}
106+
107+
// V1:深度遍历,结果指针作为参数传入到函数内部
108+
func dfs(root *TreeNode, result *[]int) {
109+
if root == nil {
110+
return
111+
}
112+
*result = append(*result, root.Val)
113+
dfs(root.Left, result)
114+
dfs(root.Right, result)
115+
}
116+
117+
// DFS 深度搜索-从下向上(分治法)
118+
func preorderTraversalDFSDivide(root *TreeNode) []int {
119+
result := divideAndConquer(root)
120+
121+
return result
122+
}
123+
func divideAndConquer(root *TreeNode) []int {
124+
result := make([]int, 0)
125+
// 返回条件(null & leaf)
126+
if root == nil {
127+
return result
128+
}
129+
// 分治(Divide)
130+
left := divideAndConquer(root.Left)
131+
right := divideAndConquer(root.Right)
132+
// 合并结果(Conquer)
133+
result = append(result, root.Val)
134+
result = append(result, left...)
135+
result = append(result, right...)
136+
137+
return result
138+
}
139+
140+
// BFS 层次遍历
141+
func levelOrderBFS(root *TreeNode) [][]int {
142+
// 通过上一层的长度确定下一层的元素
143+
result := make([][]int, 0)
144+
if root == nil {
145+
return result
146+
}
147+
queue := make([]*TreeNode, 0)
148+
queue = append(queue, root)
149+
for len(queue) > 0 {
150+
list := make([]int, 0)
151+
// 为什么要取length?
152+
// 记录当前层有多少元素(遍历当前层,再添加下一层)
153+
l := len(queue)
154+
for i := 0; i < l; i++ {
155+
// 出队列
156+
level := queue[0]
157+
queue = queue[1:]
158+
list = append(list, level.Val)
159+
if level.Left != nil {
160+
queue = append(queue, level.Left)
161+
}
162+
if level.Right != nil {
163+
queue = append(queue, level.Right)
164+
}
165+
}
166+
result = append(result, list)
167+
}
168+
169+
return result
170+
}
171+
172+
// 归并排序
173+
func MergeSort(nums []int) []int {
174+
return mergeSort(nums)
175+
}
176+
func mergeSort(nums []int) []int {
177+
if len(nums) <= 1 {
178+
return nums
179+
}
180+
// 分治法:divide 分为两段
181+
mid := len(nums) / 2
182+
left := mergeSort(nums[:mid])
183+
right := mergeSort(nums[mid:])
184+
// 合并两段数据
185+
result := merge(left, right)
186+
return result
187+
}
188+
func merge(left, right []int) (result []int) {
189+
// 两边数组合并游标
190+
l := 0
191+
r := 0
192+
// 注意不能越界
193+
for l < len(left) && r < len(right) {
194+
// 谁小合并谁
195+
if left[l] > right[r] {
196+
result = append(result, right[r])
197+
r++
198+
} else {
199+
result = append(result, left[l])
200+
l++
201+
}
202+
}
203+
// 剩余部分合并
204+
result = append(result, left[l:]...)
205+
result = append(result, right[r:]...)
206+
return
207+
}
208+
209+
// 快速排序
210+
func QuickSort(nums []int) []int {
211+
// 思路:把一个数组分为左右两段,左段小于右段,类似分治法没有合并过程
212+
quickSort(nums, 0, len(nums)-1)
213+
return nums
214+
215+
}
216+
func quickSort(nums []int, start, end int) {
217+
// 原地交换,所以传入交换索引
218+
if start < end {
219+
// 分治法:divide
220+
pivot := partition(nums, start, end)
221+
quickSort(nums, 0, pivot-1)
222+
quickSort(nums, pivot+1, end)
223+
}
224+
}
225+
func partition(nums []int, start, end int) int {
226+
// 分区
227+
p := nums[end]
228+
i := start
229+
for j := start; j < end; j++ {
230+
if nums[j] < p {
231+
swap(nums, i, j)
232+
i++
233+
}
234+
}
235+
// 把中间的值换为用于比较的基准值
236+
swap(nums, i, end)
237+
return i
238+
}
239+
func swap(nums []int, i, j int) {
240+
t := nums[i]
241+
nums[i] = nums[j]
242+
nums[j] = t
243+
}

‎data_structure/binarytree_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package data_structure
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
var treeNode *TreeNode = &TreeNode{
9+
Val: 1,
10+
Left: &TreeNode{
11+
Val: 2,
12+
Left: &TreeNode{
13+
Val: 4,
14+
Right: &TreeNode{
15+
Val: 6,
16+
Left: &TreeNode{Val: 7},
17+
Right: &TreeNode{Val: 8},
18+
},
19+
},
20+
},
21+
Right: &TreeNode{
22+
Val: 3,
23+
Right: &TreeNode{Val: 5},
24+
},
25+
}
26+
27+
func TestPreorderTraversalRecursion(t *testing.T) {
28+
preorderTraversalRecursion(treeNode)
29+
}
30+
31+
func TestPreorderTraversalNotRecursion(t *testing.T) {
32+
result := preorderTraversalNotRecursion(treeNode)
33+
fmt.Println(result)
34+
}
35+
36+
func TestInorderTraversalNotRecursion(t *testing.T) {
37+
result := inorderTraversalNotRecursion(treeNode)
38+
fmt.Println(result)
39+
}
40+
41+
func TestPostorderTraversalNotRecursion(t *testing.T) {
42+
result := postorderTraversalNotRecursion(treeNode)
43+
fmt.Println(result)
44+
}
45+
46+
func TestPreorderTraversalDFS(t *testing.T) {
47+
result := preorderTraversalDFS(treeNode)
48+
fmt.Println(result)
49+
}
50+
51+
func TestPreorderTraversalDFSDivide(t *testing.T) {
52+
result := preorderTraversalDFSDivide(treeNode)
53+
fmt.Println(result)
54+
}
55+
56+
func TestLevelOrderBFS(t *testing.T) {
57+
result := levelOrderBFS(treeNode)
58+
fmt.Println(result)
59+
}
60+
61+
func TestMergeSort(t *testing.T) {
62+
nums := []int{3, 2, 9, 4, 6, 8, 1, 5}
63+
result := MergeSort(nums)
64+
fmt.Println(result)
65+
}
66+
67+
func TestQuickSort(t *testing.T) {
68+
nums := []int{3, 2, 9, 4, 6, 8, 1, 5}
69+
result := QuickSort(nums)
70+
fmt.Println(result)
71+
}

‎go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module algorithm-pattern
2+
3+
go 1.22.8

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /