二叉树
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
本文详细介绍了二叉树的各种操作实现,包括插入、删除、搜索等基本操作,以及前序、中序、后序和广度优先遍历。此外还探讨了如何查找最小公共祖先、节点层级和节点间距离等问题。
707

被折叠的 条评论
为什么被折叠?



