二叉树
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