• 二叉平衡树旋转


    二叉平衡树旋转

    二叉平衡树旋转

    二叉平衡树操作

    添加

    二叉平衡树的添加节点,首先找到对应位置增加节点,其次查看左右子树的高度差是否符合标准,不然则调整。

    删除

    二叉平衡树删除,首先和二叉排序树同样的规则,删除对应节点,主要考虑一下三点情况

    • 删除节点是叶子节点,则直接删除
    • 删除节点有左或者右节点的存在,则将其存在的节点继承该删除节点的位置,则满足二叉排序树性质
    • 删除节点存在左右节点,则找到其后继节点,替换后继节点的值,删除后继节点(也可使用前驱节点操作)

    其次删除后向上查看是否符合左右子树平衡标准,不然则调整。

    整体代码以及单测

    package AVLT
    
    type AVLT struct {
    	value int
    	h int
    	left *AVLT
    	right *AVLT
    }
    
    func InitAVLT(v int, h int) *AVLT{
    	t := AVLT{
    		value:v,
    		h:h,
    		left:nil,
    		right:nil,
    	}
    	return &t
    }
    
    func FindMax(root *AVLT) *AVLT{
    	if root == nil {
    		return nil
    	}
    	if root.right == nil {
    		return root
    	}
    	return FindMax(root.right)
    }
    
    func FindMin(root *AVLT) *AVLT{
    	if root == nil {
    		return nil
    	}
    	if root.left == nil {
    		return root
    	}
    	return FindMin(root.left)
    }
    
    func GetHeight(root *AVLT) int {
    	if root == nil {
    		return 0
    	}
    	return root.h
    }
    
    func LL(root *AVLT) *AVLT{
    	tmp := root.left
    	root.left = tmp.right
    	root.h = max(GetHeight(root.left),GetHeight(root.right)) + 1
    	tmp.right = root
    	root = tmp
    	tmp.h = max(GetHeight(tmp.left),GetHeight(tmp.right)) + 1
    	return tmp
    }
    
    func RR(root *AVLT) *AVLT{
    	tmp := root.right
    	root.right = tmp.left
    	root.h = max(GetHeight(root.left),GetHeight(root.right)) + 1
    	tmp.left = root
    	root = tmp
    	tmp.h = max(GetHeight(tmp.left),GetHeight(tmp.right)) + 1
    	return tmp
    }
    
    func LR(root *AVLT) *AVLT{
    	//tmp := root.left.RR()
    	//root.left = tmp
    	RR(root.left)
    	return LL(root)
    }
    
    func RL(root *AVLT) *AVLT{
    	//tmp := root.right.LL()
    	//root.right = tmp
    	LL(root.right)
    	return RR(root)
    }
    
    func Insert(root *AVLT,x int) *AVLT{
    	if root == nil {
    		root = InitAVLT(x,1)
    	} else if x < root.value {
    		root.left = Insert(root.left,x)
    		if GetHeight(root.left) - GetHeight(root.right) > 1 {
    			if x < root.left.value {
    				root = LL(root)
    			} else {
    				root = LR(root)
    			}
    		}
    	} else if root.value < x {
    		root.right = Insert(root.right,x)
    		if GetHeight(root.right) - GetHeight(root.left) > 1 {
    			if x > root.right.value {
    				root = RR(root)
    			} else {
    				root = RL(root)
    			}
    		}
    	}
    	root.h = max(GetHeight(root.left),GetHeight(root.right)) + 1
    	return root
    }
    
    func Delete(root *AVLT,x int) *AVLT{
    	if root == nil {
    		return nil
    	} else if root.value == x {
    		if root.left != nil && root.right != nil {
    			if GetHeight(root.left) > GetHeight(root.right) {
    				root.value = FindMax(root.left).value
    				root.left = Delete(root.left,root.value)
    			} else {
    				root.value = FindMin(root.right).value
    				root.right = Delete(root.right,root.value)
    			}
    		} else {
    			if root.left != nil {
    				root = root.left
    			} else if root.right != nil {
    				root = root.right
    			} else {
    				root = nil
    			}
    		}
    	} else if root.value > x {
    		root.left = Delete(root.left,x)
    		if GetHeight(root.right) - GetHeight(root.left) > 1 {
    			if GetHeight(root.right.left) > GetHeight(root.right.right) {
    				root = RL(root)
    			} else {
    				root = RR(root)
    			}
    		} else {
    			root.h = max(GetHeight(root.left),GetHeight(root.right)) + 1
    		}
    	} else {
    		root.right = Delete(root.right,x)
    		if GetHeight(root.left) - GetHeight(root.right) > 1 {
    			if GetHeight(root.left.left) < GetHeight(root.left.right) {
    				root = LR(root)
    			} else {
    				root = LL(root)
    			}
    		} else {
    			root.h = max(GetHeight(root.left),GetHeight(root.right)) + 1
    		}
    	}
    	return root;
    }
    
    func max(a,b int) int{
    	if a<b {
    		return b
    	}
    	return a
    }
    
    func min(a,b int) int {
    	if a<b {
    		return a
    	}
    	return b
    }
    
    func abs(a,b int) int {
    	t1 := a-b
    	if t1<0 {
    		t1 = -1 * t1
    	}
    	t2 := b-a
    	if t2<0 {
    		t2 = -1 * t2
    	}
    	return max(t1,t2)
    }
    //===================单测=================
    package AVLT
    
    import (
    	"fmt"
    	"math/rand"
    	"testing"
    	"time"
    )
    
    
    func TestInsert(t *testing.T) {
    	a := []int{1, 2, 3, 4, 5, 6, 7, 8}
    	root := InitAVLT(0, 1)
    	for i, _ := range a {
    		root = Insert(root, a[i])
    	}
    	PrintAVLT(root,4)
    }
    
    func TestDelete(t *testing.T) {
    	a := []int{1, 2, 3, 4, 5, 6, 7, 8}
    	ra := []int{0,1, 2, 3, 4, 5, 6, 7, 8}
    	root := InitAVLT(0, 1)
    	for i, _ := range a {
    		root = Insert(root, a[i])
    	}
    	ra = getRandomArray(ra)
    	for i,_ := range ra {
    		root  = Delete(root,ra[i])
    		//PrintAVLT(root,4)
    		PrintAVLTNoHeight(root,4)
    		fmt.Println("===============")
    	}
    }
    
    func PrintAVLT(root *AVLT, C int) {
    	if root == nil {
    		fmt.Println("weng")
    		return
    	}
    	var q []*AVLT
    	tmp := 1
    	q = append(q,root)
    	j := 0
    	c := 0
    	for j < len(q) && c < C{
    		for i:=0;i<tmp && j+i < len(q);i++{
    			if q[j+i].h == -2 {
    				fmt.Printf("x,x  ")
    			} else {
    				fmt.Printf("%d,%d  ",q[j+i].value,q[j+i].h)
    			}
    			if q[j+i].left != nil && q[j+i].right != nil{
    				q = append(q,q[j+i].left)
    				q = append(q,q[j+i].right)
    			} else if q[j+i].left == nil && q[j+i].right != nil{
    				q = append(q,&AVLT{0,-2,nil,nil})
    				q = append(q,q[j+i].right)
    			} else if q[j+i].left != nil && q[j+i].right == nil{
    				q = append(q,q[j+i].left)
    				q = append(q,&AVLT{0,-2,nil,nil})
    			} else  {
    				q = append(q,&AVLT{0,-2,nil,nil})
    				q = append(q,&AVLT{0,-2,nil,nil})
    			}
    		}
    		fmt.Println()
    		j += tmp
    		tmp = tmp * 2
    		c += 1
    	}
    }
    
    func PrintAVLTNoHeight(root *AVLT, C int) {
    	if root == nil {
    		fmt.Println("weng")
    		return
    	}
    	var q []*AVLT
    	tmp := 1
    	q = append(q,root)
    	j := 0
    	c := 0
    	for j < len(q) && c < C{
    		for i:=0;i<tmp && j+i < len(q);i++{
    			if q[j+i].h == -2 {
    				fmt.Printf("x  ")
    			} else {
    				fmt.Printf("%d  ",q[j+i].value)
    			}
    			if q[j+i].left != nil && q[j+i].right != nil{
    				q = append(q,q[j+i].left)
    				q = append(q,q[j+i].right)
    			} else if q[j+i].left == nil && q[j+i].right != nil{
    				q = append(q,&AVLT{0,-2,nil,nil})
    				q = append(q,q[j+i].right)
    			} else if q[j+i].left != nil && q[j+i].right == nil{
    				q = append(q,q[j+i].left)
    				q = append(q,&AVLT{0,-2,nil,nil})
    			} else  {
    				q = append(q,&AVLT{0,-2,nil,nil})
    				q = append(q,&AVLT{0,-2,nil,nil})
    			}
    		}
    		fmt.Println()
    		j += tmp
    		tmp = tmp * 2
    		c += 1
    	}
    }
    
    func getRandomArray(vs []int) []int {
    	rand.Seed(time.Now().UnixNano())
    	for i := 0; i < 6; i++ {
    		ri := rand.Intn(6)
    		tmp := vs[i]
    		vs[i] = vs[ri]
    		vs[ri] = tmp
    	}
    	return vs
    }
    
  • 相关阅读:
    centos6 LVS-DR模式---分析
    centos6.6 安装 LXC
    Amoeba-mysql读写分离实战
    keepalived +mysql 实战
    nginx添加sticky模块-cookie保持会话
    haproxy转发真实IP给web
    Mysql-如何正确的使用索引以及索引的原理
    Mysql-自带的一些功能,基本用法(视图,触发器,事务,存储过程,函数,流程控制)
    Mysql-常用数据的基本操作和基本形式
    Mysql-多表连接的操作和用法
  • 原文地址:https://www.cnblogs.com/weiweng/p/12486342.html
Copyright © 2020-2023  润新知