go语言实现二叉排序树及其前序遍历

结构  左右指针和存值的一个int  (这边其实可以再添加一个指向根节点的指针,那所有节点都可以获得根节点)

type AVL struct{
	left,right *AVL
	value int
}

获取左右节点的指针

func (a *AVL)getLeft()(*AVL)  {
	if a.left != nil{
		return a.left
	}
	return nil
}


func (a *AVL)getRight()(*AVL)  {
	if a.right != nil{
		return a.right
	}
	return nil
}

 

新建节点

func NewAVLNode(value int,left,right *AVL) *AVL {
	node := &AVL{value:value,left:left,right:right}
	return node
}

查找节点

当节点值大于所需要查找的值时,把当前节点的右节点当做根节点,然后继续向下找

当节点值小于所需要查找的值时,把当前节点的左节点当做根节点,然后继续向下找

func (root *AVL)Find(value int) (*AVL) {
	var result *AVL
	for true{
		if value > root.value {
			root = root.right
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if value < root.value{
			root = root.left
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else {
			result = root
			return result
		}
	}
	return result
}

 插入

func (root *AVL)Insert(a *AVL)  {
	for true{
		if a.value > root.value {
			if root.right == nil{
				root.right = a
				return
			}
			root = root.right

		}else if a.value < root.value{
			if root.left == nil{
				root.left = a
				//root = root1
				return
			}
			root = root.left
		}else {
			fmt.Println("元素已存在")
			return
		}
	}
}

查找元素与先序遍历

func (a *AVL)FindPrint(i int)  {
	result := a.Find(i)
	if result != nil{
		fmt.Println(result.value)
	}

}

//先序遍历
func (a *AVL)LeftPrint()  {
	if a.left != nil {
		l := a.left
		l.LeftPrint()
	}
	fmt.Println(a.value)
	if a.right != nil {
		r := a.right
		r.LeftPrint()
	}
}

//两种方法
//先序遍历
func LeftPrint(node *AVL)  {
	if node != nil {
		LeftPrint(node.left)
		fmt.Print("  ")
		fmt.Print(node.value)
		LeftPrint(node.right)
	}
}

查找前驱节点与删除元素


func (root *AVL)FindBefore(value int) (*AVL) {
	var result *AVL
	if value == root.value{
		fmt.Println("不能移除根节点")
		return nil
	}
	for true{
		if (root.right != nil && value == root.right.value )||(root.left != nil && value == root.left.value) {
			return root
		} else if value > root.value {
			root = root.right
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if value < root.value{
			root = root.left
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if root.left == nil && root .right == nil {
			fmt.Println("不存在")
			break
		}
	}
	return result
}

//删除元素

func (a *AVL)Remove1(v int)  {
	rm := a.Find(v)
	be := a.FindBefore(v)
	if rm != nil && be != nil {
		//要删除的元素的左右节点都为空
		if rm.left == nil && rm.right == nil{
			if rm.value > be.value{
				be.right = nil
			}else {
				be.left = nil
			}
		}else if rm.left == nil && rm.right != nil{
			//左节点为空 右节点不为空
			if rm.value > be.value{
				be.right = rm.right
			}else {
				be.left = rm.right
			}

		}else if rm.left != nil && rm.right == nil{
			//左节点不为空 右节点为空
			if rm.value > be.value{
				be.right = rm.left
			}else {
				be.left = rm.left
			}


		}else {
			//左节点不为空 右节点不为空

			//把前驱节点的指针断开
			if rm.value > be.value{
				be.right = nil
			}else {
				be.left = nil
			}
			//把rm.left及其下面的节点 以 rm.left 为代表作为一个整体重新插入
			a.Insert(rm.left)
			a.Insert(rm.right)
		}
	}

}

结果图

 

最后完整的代码

package main

import (
	"fmt"
	"math/rand"
)

type AVL struct{
	left,right *AVL
	value int
}

func (a *AVL)getLeft()(*AVL)  {
	if a.left != nil{
		return a.left
	}
	return nil
}


func (a *AVL)getRight()(*AVL)  {
	if a.right != nil{
		return a.right
	}
	return nil
}


func NewAVLNode(value int,left,right *AVL) *AVL {
	node := &AVL{value:value,left:left,right:right}
	return node
}

func (root *AVL)Find(value int) (*AVL) {
	var result *AVL
	for true{
		if value > root.value {
			root = root.right
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if value < root.value{
			root = root.left
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else {
			result = root
			return result
		}
	}
	return result
}


func (root *AVL)Insert(a *AVL)  {
	for true{
		if a.value > root.value {
			if root.right == nil{
				root.right = a
				return
			}
			root = root.right

		}else if a.value < root.value{
			if root.left == nil{
				root.left = a
				//root = root1
				return
			}
			root = root.left
		}else {
			fmt.Println("元素已存在")
			return
		}
	}
}

func (a *AVL)FindPrint(i int)  {
	result := a.Find(i)
	if result != nil{
		fmt.Println(result.value)
	}

}

//先序遍历
func (a *AVL)LeftPrint()  {
	if a.left != nil {
		l := a.left
		l.LeftPrint()
	}
	fmt.Print("  ")
	fmt.Print(a.value)
	if a.right != nil {
		r := a.right
		r.LeftPrint()
	}
}


func (root *AVL)FindBefore(value int) (*AVL) {
	var result *AVL
	if value == root.value{
		fmt.Println("不能移除根节点")
		return nil
	}
	for true{
		if (root.right != nil && value == root.right.value )||(root.left != nil && value == root.left.value) {
			return root
		} else if value > root.value {
			root = root.right
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if value < root.value{
			root = root.left
			if root == nil{
				fmt.Println("不存在")
				break
			}
		}else if root.left == nil && root .right == nil {
			fmt.Println("不存在")
			break
		}
	}
	return result
}

//删除元素

func (a *AVL)Remove1(v int)  {
	rm := a.Find(v)
	be := a.FindBefore(v)
	if rm != nil && be != nil {
		//要删除的元素的左右节点都为空
		if rm.left == nil && rm.right == nil{
			if rm.value > be.value{
				be.right = nil
			}else {
				be.left = nil
			}
		}else if rm.left == nil && rm.right != nil{
			//左节点为空 右节点不为空
			if rm.value > be.value{
				be.right = rm.right
			}else {
				be.left = rm.right
			}

		}else if rm.left != nil && rm.right == nil{
			//左节点不为空 右节点为空
			if rm.value > be.value{
				be.right = rm.left
			}else {
				be.left = rm.left
			}


		}else {
			//左节点不为空 右节点不为空

			//把前驱节点的指针断开
			if rm.value > be.value{
				be.right = nil
			}else {
				be.left = nil
			}
			//把rm.left及其下面的节点 以 rm.left 为代表作为一个整体重新插入
			a.Insert(rm.left)
			a.Insert(rm.right)
		}
	}

}



func main()  {
	//var root *AVL
	var root  = &AVL{nil,nil,50}
	//rand.Seed(time.Now().UnixNano())
	for i := 0;i<20;i++{
		v := rand.Intn(100)
		fmt.Println(v)
		node := NewAVLNode(v,nil,nil)
		root.Insert(node)
	}
	root.LeftPrint()
	root.Remove1(47)
	fmt.Println("")
	root.LeftPrint()

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值