二叉树的增删改查,深度、距离,前序、中序、后序遍历,广度优先遍历(GO语言)

二叉树

package main

import (
    "github.com/cheekybits/genny/generic"
    "sync"
    "fmt"
)

type Item generic.Type

//节点的结构
type Node struct {
    key   int
    value Item
    left  *Node
    right *Node
}

//树的结构
type ItemBinarySearchTree struct {
    root *Node
    lock sync.RWMutex
}

//格式化输出
func (tree *ItemBinarySearchTree) String() {
    tree.lock.Lock()
    defer tree.lock.Unlock()
    fmt.Println("格式化输出:")
    fmt.Println("--------------------------------")
    stringify(tree.root, 0)
    fmt.Println("--------------------------------")
}

func stringify(node *Node, level int) {
    if node != nil {
        format := ""
        for i := 0; i < level; i++ {
            format += "       "
        }

        format += "---[ "
        level++

        stringify(node.right, level)
        fmt.Printf(format+"%d\n", node.key)
        stringify(node.left, level)
    }
}

//插入节点
func (tree *ItemBinarySearchTree) Insert(key int, value Item) {
    tree.lock.Lock()
    defer tree.lock.Unlock()
    node := &Node{key, value, nil, nil}
    if tree.root == nil {
        tree.root = node
    } else {
        insertNode(tree.root, node)
    }
}

func insertNode(node, newNode *Node) {
    if newNode.key < node.key {
        if node.left == nil {
            node.left = newNode
        } else {
            insertNode(node.left, newNode)
        }
    } else {
        if node.right == nil {
            node.right = newNode
        } else {
            insertNode(node.right, newNode)
        }
    }
}

//最小节点
func (tree *ItemBinarySearchTree) Min() *Item {
    tree.lock.RLock()
    defer tree.lock.RUnlock()
    node := tree.root

    if node == nil {
        return nil
    }

    for {
        if node.left == nil {
            return &node.value
        }

        node = node.left
    }
}

//最大节点
func (tree *ItemBinarySearchTree) Max() Item {
    tree.lock.RLock()
    defer tree.lock.RUnlock()

    node := tree.root

    if node == nil {
        return nil
    }

    for {
        if node.right == nil {
            return node.value
        }
        node = node.right
    }
}

//搜索某个值
func (tree *ItemBinarySearchTree) Search(key int) bool {
    tree.lock.RLock()
    defer tree.lock.RUnlock()
    fmt.Print("是否存在节点:", key, "\t")
    return search(tree.root, key)
}

func search(node *Node, key int) bool {
    if node == nil {
        return false
    }

    if key < node.key {
        return search(node.left, key)
    }

    if key > node.key {
        return search(node.right, key)
    }

    return true
}

//删除节点
func (tree *ItemBinarySearchTree) Remove(key int) {
    tree.lock.Lock()
    defer tree.lock.Unlock()
    fmt.Println("删除节点:", key)
    remove(tree.root, key)
}

func remove(node *Node, key int) *Node {
    if node == nil {
        return nil
    }

    if key < node.key {
        node.left = remove(node.left, key)
        return node
    }

    if key > node.key {
        node.right = remove(node.right, key)
        return node
    }

    if node.left == nil && node.right == nil {
        node = nil
        return node
    }

    if node.left == nil {
        node = node.right
        return node
    }

    if node.right == nil {
        node = node.left
        return node
    }

    mostLeftNode := node.right
    for {
        if mostLeftNode != nil && mostLeftNode.left != nil {
            mostLeftNode = mostLeftNode.left
        } else {
            break
        }
    }

    node.key, node.value = mostLeftNode.key, mostLeftNode.value
    node.right = remove(node.right, node.key)
    return node
}

//前序遍历
func (tree *ItemBinarySearchTree) PreOrderTraverse(node *Node) {
    if node == nil {
        return
    }
    fmt.Print(node.value, "\t")
    tree.PreOrderTraverse(node.left)
    tree.PreOrderTraverse(node.right)
}

//后序遍历
func (tree *ItemBinarySearchTree) PostOrderTraverse() {
    tree.lock.Lock()
    defer tree.lock.Unlock()
    fmt.Println("后序遍历:")
    node := tree.root
    postOrder(node)
    fmt.Println()
}

func postOrder(node *Node) {
    if node == nil {
        return
    }
    postOrder(node.left)
    postOrder(node.right)
    fmt.Print(node.value, "\t")
}

//中序遍历
func (tree *ItemBinarySearchTree) InOrderTraverse() {
    fmt.Println("中序遍历:")
    node := tree.root
    InOrder(node)
    fmt.Println()
}

func InOrder(node *Node) {
    if node != nil {
        InOrder(node.left)
        fmt.Print(node.key, "\t")
        InOrder(node.right)
    }
}

//广度优先
func breadthFirst(node *Node) []Item {
    fmt.Println("广度优先遍历:")
    var result []Item
    var nodes = []Node{*node}

    for len(nodes) > 0 {
        node := nodes[0]
        nodes = nodes[1:]
        result = append(result, node.value)
        if node.left != nil {
            nodes = append(nodes, *node.left)
        }
        if node.right != nil {
            nodes = append(nodes, *node.right)
        }
    }

    return result
}

//二叉树的深度
func GetDepth(node *Node) int {
    depth := 0
    if node != nil {
        depth = max(GetDepth(node.left), GetDepth(node.right)) + 1
    }
    return depth
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func GetDepth2(node *Node) int {
    if node == nil {
        return 0
    }
    return max(GetDepth2(node.left), GetDepth2(node.right)) + 1
}

//找出两个节点的最小共同父节点
func (tree *ItemBinarySearchTree) FindLCA(node *Node, key1 int, key2 int) {
    fmt.Print(key1, "和", key2, "的最小共同父节点为:")
    lca := findLCA(node, key1, key2)
    fmt.Println(lca.key)
}

func findLCA(node *Node, key1 int, key2 int) *Node {
    if node == nil {
        return nil
    }
    if node.key == key1 || node.key == key2 {
        return node
    }
    var leftNode = new(Node)
    leftNode = findLCA(node.left, key1, key2)
    var rightNode = new(Node)
    rightNode = findLCA(node.right, key1, key2)
    if leftNode != nil && rightNode != nil {
        return node
    }
    if leftNode != nil {
        return leftNode
    }
    return rightNode
}

//二叉树的深度
func (tree *ItemBinarySearchTree) FindLevel(node *Node, key int) {
    level := 1
    lev := findLevel(node, key, level)
    fmt.Println(key, "在第", lev, "层。")
}

func findLevel(node *Node, key int, level int) int {
    if node == nil {
        return -1
    }
    if node.key == key {
        return level
    }
    var lev int
    lev = findLevel(node.left, key, level+1)
    if lev == -1 {
        return findLevel(node.right, key, level+1)
    } else {
        return lev
    }
}

//任意两个节点的距离
func GetDistance(node *Node, key1 int, key2 int) {
    fmt.Print(key1, "和", key2, "的距离为:")
    dis := getDistance(node, key1, key2)
    fmt.Println(dis)
}

func getDistance(node *Node, key1 int, key2 int) int {
    lca := findLCA(node, key1, key2)
    disLCA := findLevel(node, lca.key, 1)
    disKey1 := findLevel(node, key1, 1)
    disKey2 := findLevel(node, key2, 1)
    dis := disKey1 + disKey2 - 2*disLCA
    return dis
}

func main() {
    var tree ItemBinarySearchTree
    tree.Insert(8, "8")
    tree.Insert(4, "4")
    tree.Insert(13, "13")
    tree.Insert(2, "2")
    tree.Insert(6, "6")
    tree.Insert(1, "1")
    tree.Insert(10, "10")
    tree.Insert(12, "12")
    tree.Insert(3, "3")
    tree.Insert(9, "9")
    tree.Insert(5, "5")
    tree.Insert(7, "7")
    tree.Insert(11, "11")

    tree.String()

    fmt.Printf("二叉树key最小的节点的value值:%v\n", *tree.Min())
    //fmt.Printf("二叉树key最大的节点的value值:%v\n", tree.Max())
    fmt.Println("最大的节点是:", tree.Max())

    fmt.Println(tree.Search(16))

    tree.Remove(8)
    tree.String()

    fmt.Println("前序遍历:")
    tree.PreOrderTraverse(tree.root)
    fmt.Println()

    tree.InOrderTraverse()

    tree.PostOrderTraverse()

    breadthTree := breadthFirst(tree.root)
    fmt.Println(breadthTree)

    fmt.Println("广度优先遍历:")
    for _, value := range breadthTree {
        fmt.Print(value, "\t")
        //fmt.Println(value)
    }
    fmt.Println()

    fmt.Print("二叉树的深度:")
    fmt.Println(GetDepth(tree.root))

    fmt.Print("二叉树的深度为:")
    fmt.Println(GetDepth2(tree.root))

    tree.FindLCA(tree.root, 3, 11)

    tree.FindLevel(tree.root, 11)

    GetDistance(tree.root, 4, 10)

}

运行结果

格式化输出:
--------------------------------
       ---[ 13
                     ---[ 12
                            ---[ 11
              ---[ 10
                     ---[ 9
---[ 8
                     ---[ 7
              ---[ 6
                     ---[ 5
       ---[ 4
                     ---[ 3
              ---[ 2
                     ---[ 1
--------------------------------
二叉树key最小的节点的value值:1
最大的节点是: 13
是否存在节点:16   false
删除节点: 8
格式化输出:
--------------------------------
       ---[ 13
                     ---[ 12
                            ---[ 11
              ---[ 10
---[ 9
                     ---[ 7
              ---[ 6
                     ---[ 5
       ---[ 4
                     ---[ 3
              ---[ 2
                     ---[ 1
--------------------------------
前序遍历:
9   4   2   1   3   6   5   7   13  10  12  11  
中序遍历:
1   2   3   4   5   6   7   9   10  11  12  13  
后序遍历:
1   3   2   5   7   6   4   11  12  10  13  9   
广度优先遍历:
[9 4 13 2 6 10 1 3 5 7 12 11]
广度优先遍历:
9   4   13  2   6   10  1   3   5   7   12  11  
二叉树的深度:5
二叉树的深度为:5
3和11的最小共同父节点为:9
11 在第 5 层。
4和10的距离为:3
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值