- 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)
- }