(三)用go實現平衡二叉樹
阿新 • • 發佈:2021-10-29
本篇,我們用go簡單的實現平衡二叉查詢樹。具體原理參考大佬部落格即可:AVL樹(一)之 圖文解析 和 C語言的實現
1.節點定義
type AVLNode struct{
data int
height int
left, right *AVLNode
}
2.樹的遍歷
// 前序遍歷 func PreTraverse(p *AVLNode) { if p == nil { return } fmt.Printf("%d:%d ", p.data, p.height) if p.left != nil { PreTraverse(p.left) } if p.right != nil { PreTraverse(p.right) } } // 中序遍歷 func InTraverse(p *AVLNode) { if p == nil { return } if p.left != nil { InTraverse(p.left) } fmt.Printf("%d ", p.data) if p.right != nil { InTraverse(p.right) } } // 後序遍歷 func PostTraverse(p *AVLNode) { if p == nil { return } if p.left != nil { PostTraverse(p.left) } if p.right != nil { PostTraverse(p.right) } fmt.Printf("%d ", p.data) }
3.樹的旋轉
// LL的旋轉 func ll_rotate(k2 *AVLNode) *AVLNode { var k1 *AVLNode = k2.left k2.left = k1.right k1.right = k2 k2.height = max(height(k2.left), height(k2.right)) + 1 k1.height = max(height(k1.left), k2.height) + 1 return k1 } // RR的旋轉 func rr_rotate(k1 *AVLNode) *AVLNode { var k2 *AVLNode = k1.right k1.right = k2.left k2.left = k1 k1.height = max(height(k1.left), height(k1.right)) + 1 k2.height = max(height(k2.right), k1.height) + 1 return k2 } // LR的旋轉 func lr_rotate(k3 *AVLNode) *AVLNode { k3.left = rr_rotate(k3.left) return ll_rotate(k3) } // RL的旋轉 func rl_rotate(k1 *AVLNode) *AVLNode { k1.right = ll_rotate(k1.right) return rr_rotate(k1) }
4.插入節點
// 插入節點 func Add(p *AVLNode, data int) *AVLNode { if p == nil { p = new(AVLNode) p.data = data p.height = 1 return p } if data < p.data { p.left = Add(p.left, data) if height(p.left) - height(p.right) == 2 { if data > p.left.data { fmt.Println("lr") p = lr_rotate(p) } else { fmt.Println("ll") p = ll_rotate(p) } } } else if data > p.data { p.right = Add(p.right, data) if height(p.right) - height(p.left) == 2{ if data > p.right.data { fmt.Println("rr") p = rr_rotate(p) } else { fmt.Println("rl") p = rl_rotate(p) } } } else { fmt.Println("Add fail: not allowed same data!") } p.height = max(height(p.left), height(p.right)) + 1 fmt.Printf("節點:%d, 高度:%d\n", p.data, p.height) return p }
5.查詢節點
// 查詢節點
func Find(p *AVLNode, data int) *AVLNode {
if p.data == data {
return p
} else if data < p.data {
if p.left != nil {
return Find(p.left, data)
}
return nil
} else {
if p.right != nil {
return Find(p.right, data)
}
return nil
}
}
// 最大節點
func maxNode(p *AVLNode) *AVLNode {
if p == nil {
return nil
}
for p.right != nil {
p = p.right
}
return p
}
// 最小節點
func minNode(p *AVLNode) *AVLNode {
if p == nil {
return nil
}
for p.left != nil {
p = p.left
}
return p
}
6.刪除節點
// 刪除節點
func Delete(p *AVLNode, data int) *AVLNode {
node := Find(p, data)
if node != nil {
return delete(p, node)
}
return nil
}
func delete(p, node *AVLNode) *AVLNode {
if node.data < p.data {
p.left = delete(p.left, node)
if height(p.right) - height(p.left) == 2 {
if height(p.right.right) > height(p.right.left) {
p = rr_rotate(p)
} else {
p = rl_rotate(p)
}
}
} else if node.data > p.data {
p.right = delete(p.right, node)
if height(p.left) - height(p.right) == 2 {
if height(p.left.right) > height(p.left.left) {
p = lr_rotate(p)
} else {
p = ll_rotate(p)
}
}
} else {
// 左右孩子都非空
if (p.left != nil) && (p.right != nil) {
if height(p.left) > height(p.right) {
var max *AVLNode = maxNode(p.left)
p.data = max.data
p.left = delete(p.left, max)
} else {
var min *AVLNode = minNode(p.right)
p.data = min.data
p.right = delete(p.right, min)
}
} else {
if p.left != nil {
p = p.left
} else {
p = p.right
}
}
}
if p != nil {
p.height = max(height(p.left), height(p.right)) + 1
}
return p
}
7.完整程式碼
package main
import (
"fmt"
)
type AVLNode struct{
data int
height int
left, right *AVLNode
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func height(p *AVLNode) int {
if p != nil {
return p.height
}
return 0
}
// 前序遍歷
func PreTraverse(p *AVLNode) {
if p == nil {
return
}
fmt.Printf("%d:%d ", p.data, p.height)
if p.left != nil {
PreTraverse(p.left)
}
if p.right != nil {
PreTraverse(p.right)
}
}
// 中序遍歷
func InTraverse(p *AVLNode) {
if p == nil {
return
}
if p.left != nil {
InTraverse(p.left)
}
fmt.Printf("%d ", p.data)
if p.right != nil {
InTraverse(p.right)
}
}
// 後序遍歷
func PostTraverse(p *AVLNode) {
if p == nil {
return
}
if p.left != nil {
PostTraverse(p.left)
}
if p.right != nil {
PostTraverse(p.right)
}
fmt.Printf("%d ", p.data)
}
// LL的旋轉
func ll_rotate(k2 *AVLNode) *AVLNode {
var k1 *AVLNode = k2.left
k2.left = k1.right
k1.right = k2
k2.height = max(height(k2.left), height(k2.right)) + 1
k1.height = max(height(k1.left), k2.height) + 1
return k1
}
// RR的旋轉
func rr_rotate(k1 *AVLNode) *AVLNode {
var k2 *AVLNode = k1.right
k1.right = k2.left
k2.left = k1
k1.height = max(height(k1.left), height(k1.right)) + 1
k2.height = max(height(k2.right), k1.height) + 1
return k2
}
// LR的旋轉
func lr_rotate(k3 *AVLNode) *AVLNode {
k3.left = rr_rotate(k3.left)
return ll_rotate(k3)
}
// RL的旋轉
func rl_rotate(k1 *AVLNode) *AVLNode {
k1.right = ll_rotate(k1.right)
return rr_rotate(k1)
}
// 插入節點
func Add(p *AVLNode, data int) *AVLNode {
if p == nil {
p = new(AVLNode)
p.data = data
p.height = 1
return p
}
if data < p.data {
p.left = Add(p.left, data)
if height(p.left) - height(p.right) == 2 {
if data > p.left.data {
fmt.Println("lr")
p = lr_rotate(p)
} else {
fmt.Println("ll")
p = ll_rotate(p)
}
}
} else if data > p.data {
p.right = Add(p.right, data)
if height(p.right) - height(p.left) == 2{
if data > p.right.data {
fmt.Println("rr")
p = rr_rotate(p)
} else {
fmt.Println("rl")
p = rl_rotate(p)
}
}
} else {
fmt.Println("Add fail: not allowed same data!")
}
p.height = max(height(p.left), height(p.right)) + 1
fmt.Printf("節點:%d, 高度:%d\n", p.data, p.height)
return p
}
// 查詢節點
func Find(p *AVLNode, data int) *AVLNode {
if p.data == data {
return p
} else if data < p.data {
if p.left != nil {
return Find(p.left, data)
}
return nil
} else {
if p.right != nil {
return Find(p.right, data)
}
return nil
}
}
// 最大節點
func maxNode(p *AVLNode) *AVLNode {
if p == nil {
return nil
}
for p.right != nil {
p = p.right
}
return p
}
// 最小節點
func minNode(p *AVLNode) *AVLNode {
if p == nil {
return nil
}
for p.left != nil {
p = p.left
}
return p
}
// 刪除節點
func Delete(p *AVLNode, data int) *AVLNode {
node := Find(p, data)
if node != nil {
return delete(p, node)
}
return nil
}
func delete(p, node *AVLNode) *AVLNode {
if node.data < p.data {
p.left = delete(p.left, node)
if height(p.right) - height(p.left) == 2 {
if height(p.right.right) > height(p.right.left) {
p = rr_rotate(p)
} else {
p = rl_rotate(p)
}
}
} else if node.data > p.data {
p.right = delete(p.right, node)
if height(p.left) - height(p.right) == 2 {
if height(p.left.right) > height(p.left.left) {
p = lr_rotate(p)
} else {
p = ll_rotate(p)
}
}
} else {
// 左右孩子都非空
if (p.left != nil) && (p.right != nil) {
if height(p.left) > height(p.right) {
var max *AVLNode = maxNode(p.left)
p.data = max.data
p.left = delete(p.left, max)
} else {
var min *AVLNode = minNode(p.right)
p.data = min.data
p.right = delete(p.right, min)
}
} else {
if p.left != nil {
p = p.left
} else {
p = p.right
}
}
}
if p != nil {
p.height = max(height(p.left), height(p.right)) + 1
}
return p
}
func main() {
//num := []int{50, 30, 20, 25, 70, 90, 100}
num := []int{3, 2, 1, 4, 5, 6, 7, 16, 15, 14, 13, 12, 11, 10, 8, 9}
var root *AVLNode
for _, v := range num {
fmt.Printf("插入節點:%d\n", v)
root = Add(root, v)
}
fmt.Println("前序遍歷:")
PreTraverse(root)
fmt.Printf("\n")
fmt.Println("中序遍歷:")
InTraverse(root)
fmt.Printf("\n")
fmt.Println("後序遍歷:")
PostTraverse(root)
fmt.Printf("\n")
avlnode := Find(root, 60)
if avlnode != nil {
fmt.Println("查詢結果:")
fmt.Printf("節點:%d 左子節點:%d 右子節點:%d\n", avlnode.data, avlnode.left.data, avlnode.right.data)
}
root = Delete(root, 8)
fmt.Println("刪除後前序遍歷:")
PreTraverse(root)
fmt.Printf("\n")
fmt.Println("刪除後中序遍歷:")
InTraverse(root)
fmt.Printf("\n")
}