package main
import (
"container/list"
"fmt"
)
type Node struct {
data any
left *Node
right *Node
}
type Tree struct {
root *Node
}
// 创建一颗二叉搜索树left < root < right(条件)
func (t *Tree) createTree(root *Node, data interface{}) *Node {
if root == nil {
node := &Node{
data: data,
left: nil,
right: nil,
}
return node
}
// 比较时,需要具体的类型
if data.(int) < root.data.(int) {
root.left = t.createTree(root.left, data)
} else {
root.right = t.createTree(root.right, data)
}
return root
}
// 前序遍历
func (t *Tree) QDisplay(root *Node) {
if root == nil {
return
}
fmt.Println(root.data)
t.QDisplay(root.left)
t.QDisplay(root.right)
}
// 非递归前序遍历
func (t *Tree) NoQDisplay(root *Node) {
if root == nil {
return
}
curr := root
st := list.New()
st.PushBack(curr)
for curr != nil || st.Len() != 0 {
t := st.Back()
st.Remove(t)
m := t.Value.(*Node)
fmt.Println(m.data)
if m.right != nil {
st.PushBack(m.right)
}
if m.left != nil {
st.PushBack(m.left)
}
}
}
// 中序遍历
func (t *Tree) ZDisplay(root *Node) {
if root == nil {
return
}
t.ZDisplay(root.left)
fmt.Println(root.data)
t.ZDisplay(root.right)
}
// 中序遍历非递归,左 - 根 - 右
func (t *Tree) NoZDisplay(root *Node) {
if root == nil {
return
}
// 借助栈结构,先进后出
curr := root
stack := list.New()
for curr != nil || stack.Len() != 0 {
if curr != nil {
// 所有的左子树放入栈中
stack.PushBack(curr)
curr = curr.left
} else {
tmp := stack.Back()
stack.Remove(tmp)
if tmp.Value != nil {
fmt.Println(tmp.Value.(*Node).data)
curr = tmp.Value.(*Node).right // 让当前出栈的节点的右子树进栈
}
}
}
}
// 后序遍历
func (t *Tree) HDisplay(root *Node) {
if root == nil {
return
}
t.HDisplay(root.left)
t.HDisplay(root.right)
fmt.Println(root.data)
}
// 后序遍历非递归
// 后续遍历解决的问题
// 当给定一个节点时,输出该节点的所有祖先
// 输出根结点到叶子节点的所有路径
// 求每条路径上的节点值之和
func (t *Tree) NoHDisplay(root *Node) {
if root == nil {
return
}
var pre *Node = nil
stack := list.New()
for root != nil || stack.Len() != 0 {
// 将左右左子树存放到栈中
for root != nil {
stack.PushBack(root)
root = root.left
}
// 取出节点
tmp := stack.Back()
root = tmp.Value.(*Node)
stack.Remove(tmp)
// 当前节点如果右节点为空,或者等于上次访问的节点,输出该节点,比把已经输出的节点打上标记
if root.right == nil || root.right == pre {
fmt.Println(root.data)
pre = root
root = nil // 右子树访问了,重新下一轮的从栈那元素
} else {
// 如果不能输出,重新入栈,再对当前节点的右子数重复入栈过程
stack.PushBack(root)
root = root.right
}
}
}
// 按层遍历
func (t *Tree) CDisplay(root *Node) {
if root == nil {
return
}
queue := list.New()
queue.PushBack(root)
for queue.Len() != 0 {
tmp := queue.Front()
queue.Remove(tmp)
cur := tmp.Value.(*Node)
fmt.Println(cur.data)
if cur.left != nil {
queue.PushBack(cur.left)
}
if cur.right != nil {
queue.PushBack(cur.right)
}
}
}
func main() {
t := &Tree{
root: nil,
}
number := []int{1, 4, 3, 2}
// 创建一棵树
for _, val := range number {
t.root = t.createTree(t.root, val)
}
//
// IntMap := make(map[int]int, 0)
// for i := 0; i < 20; i++ {
// num := rand.Int() % 10
// if _, ok := IntMap[num]; ok {
// continue
// }
// t.root = t.createTree(t.root, num)
// IntMap[num] = num
// }
t.QDisplay(t.root)
fmt.Println("-----------")
t.NoQDisplay(t.root)
// t.ZDisplay(t.root)
// fmt.Println("-----------")
// t.NoZDisplay(t.root)
//
// t.HDisplay(t.root)
// fmt.Println("-----------")
// t.NoHDisplay(t.root)
//
// t.CDisplay(t.root)
}