树结构-二分搜索树

1.树的定义

         树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的树,其中我们平常使用的目录就是常见的树;

          

1.1 二叉树的定义

        在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

                        

1.2 二分搜索树

            二分搜索树就是左子树的键值小于根节点,右子树键值大于根节点的树。而且左右子树是递归定义。简单来说就是任意节点左子树的树。这里主要讨论的是二分搜索树也就是二叉树。其应用在于查找表,以及字典结构的时候。其查找速度非常之快,而且可以用其求各种算法例如max ,min ,rank 等等

                       

2. 二分搜索树的代码实现

    2.1.1 instet

package arr

//二分搜索树的构建
type Two_tree struct {
	E     int
	Left  *Two_tree
	Right *Two_tree
}

var size = 0
/**
 * add二分搜索树添加
 *
 */
func (tree *Two_tree) Add(E int) {
	if tree.E == 0 && tree.Left == nil && tree.Right == nil {
		tree.E = E
		size++
	} else {
		inster(tree, E)
	}
}

//inster递归添加
func inster(tree *Two_tree, E int) {
	//递归基本问题
	if tree.E == E {
		//重复存在
		return
	} else if E < tree.E && tree.Left == nil {
		//插入左子树
		tree.Left = &Two_tree{E, nil, nil}
		return
		size++
	} else if E > tree.E && tree.Right == nil {
		//插入右子树
		tree.Right = &Two_tree{E, nil, nil}
		return
		size++
	}
	//递归转化更小问题
	if E < tree.E {
		inster(tree.Left, E)
	} else {
		inster(tree.Right, E)
	}

}

 

2.1.2 inster优化(1)

package arr

//二分搜索树的构建
type Two_tree struct {
	E     int
	Left  *Two_tree
	Right *Two_tree
}

type Root_tree struct {
	Root *Two_tree
}

var size = 0

/**
 * add二分搜索树添加
 *
 */
func (root *Root_tree) Add(E int) {
	root.Root=inster(root.Root, E)
}

//inster递归添加
func inster(tree *Two_tree, E int) *Two_tree {
	//判断是否是根
	if tree == nil {
		size++
		tree = &Two_tree{E, nil, nil}
		return tree
	}

	//递归转化更小问题
	if E < tree.E {
		tree.Left = inster(tree.Left, E)
	} else if E > tree.E {
		tree.Right = inster(tree.Right, E)
	}
	return tree
}

main.go

package main

import (
	"./arr"
	"fmt"
)

func main() {
	var tree arr.Root_tree

	tree.Add(1)
	fmt.Println(tree.Root.E)

	tree.Add(11)
	fmt.Println(tree.Root.Right.E)

	tree.Add(9)
	fmt.Println(tree.Root.Right.Left.E)

}

   

2.1.3inster优化(2)

package arr

//二分搜索树的构建
type Two_tree struct {
	E     int
	Left  *Two_tree
	Right *Two_tree
}

var (
	size           = 0
	tree *Two_tree = nil
)

/**
 * add二分搜索树添加
 *
 */
func (tree *Two_tree) Add(E int) {
	tree = inster(tree, E)
}

//inster递归添加
func inster(tree *Two_tree, E int) *Two_tree {
	//判断是否是根
	if tree == nil {
		size++
		tree = &Two_tree{E, nil, nil}
		return tree
	}

	//递归转化更小问题
	if E < tree.E {
		tree.Left = inster(tree.Left, E)
	} else if E > tree.E {
		tree.Right = inster(tree.Right, E)
	}
	return tree
}

   main.go

package main

import (
	"./arr"
	"fmt"
)

func main() {
	var tree arr.Two_tree
	fmt.Println(tree)

	tree.Add(1)
	fmt.Println(tree)
	fmt.Println(tree.Right.E)

	tree.Add(11)
	fmt.Println(tree.Right.Right.E)

	tree.Add(9)
	fmt.Println(tree.Right.Right.Left.E)

}

     

2.2 empty

/**
 * Empty二分搜索树的查询判断
 * @E int 要查询的数字
 */
func (root *Root_tree) Empty(E int) bool {
	return empty(root.Root, E)
}

//empty
func empty(tree *Two_tree, E int) bool {
	if tree == nil {
		return false
	}
	if E == tree.E {
		return true
	} else if E < tree.E {
		return empty(tree.Left, E)
	} else if E > tree.E {
		return empty(tree.Right, E)
	}
	return false
}

     

2.3二分搜索树的前序遍历

     2.3.1 前序遍历

            

/**
 * Preorder二分搜索树前置遍历
 */
func (root *Root_tree) Preorder() {
	preorder(root.Root)
}

//preorder递归前置遍历
func preorder(tree *Two_tree) {
	if tree == nil {
		return
	}
	fmt.Println(tree.E)
	preorder(tree.Left)
	preorder(tree.Right)
}

 

2.3.2 中序遍历(顺序遍历)

              

/**
 * Inorder二分搜索树的中序遍历
 */
func (root *Root_tree) Inorder() {
	inorder(root.Root)
}

//inorder递归中序遍历
func inorder(tree *Two_tree) {
	if tree == nil {
		return
	}
	preorder(tree.Left)
	fmt.Println(tree.E)
	preorder(tree.Right)
}

 

2.3.3 后序遍历

           

/**
 * Postorder二分搜索树的后序遍历
 */
func (root *Root_tree) Postorder()  {
	postorder(root.Root)
}

//postorder递归后续遍历
func postorder(tree *Two_tree)  {
	if tree == nil {
		return
	}
	preorder(tree.Left)
	preorder(tree.Right)
	fmt.Println(tree.E)
}

           

2.3.4 非递归前序遍历(深度优先遍历)

     模拟系统栈的压入和取出;

               

/**
 * PreorderNR二分搜索树的非递归前序遍历
 */
func (root *Root_tree) PreorderNR() {
	preordernr(root.Root)
}

//preordernr非递归遍历
func preordernr(tree *Two_tree) {
	l := list.New()
	//入栈第一个元素
	l.PushFront(tree)
	for l.Len() != 0 {
		//截取第一个元素并转化成结构体
		ll := l.Remove(l.Front()).(*Two_tree)
		fmt.Println(ll.E)
		if ll.Left != nil {
			l.PushFront(ll.Left)
		}
		if ll.Right != nil {
			l.PushFront(ll.Right)
		}
	}

}

 

2.3.5 层序遍历(广度优先遍历)

            

/**
 * levelorder二分搜索树的广度优先遍历
 */
func (root *Root_tree) Levelorder() {
	levelorder(root.Root)
}

//levelorder广度优先
func levelorder(tree *Two_tree)  {
	l := list.New()
	//入栈第一个元素
	l.PushBack(tree)
	for l.Len() != 0 {
		//截取第一个元素并转化成结构体
		ll := l.Remove(l.Front()).(*Two_tree)
		fmt.Println(ll.E)
		if ll.Left != nil {
			l.PushBack(ll.Left)
		}
		if ll.Right != nil {
			l.PushBack(ll.Right)
		}
	}
}

 

2.3.6 删除最小树(最大树)

/**
 * Removemin删除二分搜索树的最小值,并返回根
 */
func (root *Root_tree) Removemin() *Two_tree {
	return removemin(root.Root)
}

//removemin递归删除最小值
func removemin(tree *Two_tree) *Two_tree {
	if tree.Left == nil {
		right := tree.Right
		tree.Right = nil
		return right
	}
	//使原右子树代替左子树
	tree.Left=removemin(tree.Left)
	return tree
}

 

2.3.7 删除任意节点

                      

**        10
 *       /    \
		7     15
 *     / \    /
      2   8  11
 *     \   \  \
        3   9  12
 */
//remove 递归删除任意值
func remove(tree *Two_tree, e int) *Two_tree {
	if tree == nil {
		return nil
	}
	//寻找e的位置
	if e < tree.E {
		tree.Left = remove(tree.Left, e)
		return tree
	} else if e > tree.E {
		tree.Right = remove(tree.Right, e)
		return tree
	} else {
		//删除左子树为空
		if tree.Left == nil {
			right := tree.Right
			tree.Right = nil
			return right
		}
		//删除右子树为空
		if tree.Right == nil {
			left := tree.Left
			tree.Left = nil
			return left
		}
		//删除元素左右子树均不为空
		//找到待删除节点的最小节点,即待删除节点的右子树的最小节点
		//用这个节点代替删除节点,待删除左子树继续拼接
		successor := minimum(tree.Right)        //待删除节点的最小节点
		successor.Right = removemin(tree.Right) //删除操作
		successor.Left = tree.Left
		tree.Left = nil
		tree.Right = nil
		return successor
	}
}

 

2.3.8 全部代码奉上

bst.go

package arr

import (
	"fmt"
	"container/list"
)

//二分搜索树的构建
type Two_tree struct {
	E     int
	Left  *Two_tree
	Right *Two_tree
}

type Root_tree struct {
	Root *Two_tree
}

var size = 0

/**
 * add 二分搜索树添加
 * @E int 插入的数字
 */
func (root *Root_tree) Add(E int) {
	root.Root = add(root.Root, E)
}

/**
 * Empty 二分搜索树的查询判断
 * @E int 要查询的数字
 */
func (root *Root_tree) Empty(E int) bool {
	return empty(root.Root, E)
}

/**
 * Preorder 二分搜索树前序遍历
 */
func (root *Root_tree) Preorder() {
	preorder(root.Root)
}

/**
 * Inorder 二分搜索树的中序遍历
 */
func (root *Root_tree) Inorder() {
	inorder(root.Root)
}

/**
 * Postorder二分搜索树的后序遍历
 */
func (root *Root_tree) Postorder() {
	postorder(root.Root)
}

/**
 * PreorderNR 二分搜索树的非递归前序遍历
 */
func (root *Root_tree) PreorderNR() {
	preordernr(root.Root)
}

//preordernr 非递归遍历
func preordernr(tree *Two_tree) {
	l := list.New()
	//入栈第一个元素
	l.PushBack(tree)
	for l.Len() != 0 {
		//截取第一个元素并转化成结构体
		ll := l.Remove(l.Back()).(*Two_tree)
		fmt.Println(ll.E)
		if ll.Right != nil {
			l.PushBack(ll.Right)
		}
		if ll.Left != nil {
			l.PushBack(ll.Left)
		}
	}
}

/**
 * levelorder 二分搜索树的广度优先遍历
 */
func (root *Root_tree) Levelorder() {
	levelorder(root.Root)
}

//levelorder 广度优先
func levelorder(tree *Two_tree) {
	l := list.New()
	//入栈第一个元素
	l.PushBack(tree)
	for l.Len() != 0 {
		//截取第一个元素并转化成结构体
		ll := l.Remove(l.Front()).(*Two_tree)
		fmt.Println(ll.E)
		if ll.Left != nil {
			l.PushBack(ll.Left)
		}
		if ll.Right != nil {
			l.PushBack(ll.Right)
		}
	}
}

/**
 * minimum 查询二分搜索树的最小元素
 */
func (root *Root_tree) Minimum() *Two_tree {
	return minimum(root.Root)
}

/**
 * Removemin 删除二分搜索树的最小值,并返回根
 */
func (root *Root_tree) Removemin() *Two_tree {
	return removemin(root.Root)
}

/**
 * Remove 删除二分搜索树的任意值
 * @e int 指定的e
 */
func (root *Root_tree) Remove(e int) *Two_tree {
	return remove(root.Root, e)
}

/**        10
 *       /    \
		7     15
 *     / \    /
      2   8  11
 *     \   \  \
        3   9  12
 */
//remove 递归删除任意值
func remove(tree *Two_tree, e int) *Two_tree {
	if tree == nil {
		return nil
	}
	//寻找e的位置
	if e < tree.E {
		tree.Left = remove(tree.Left, e)
		return tree
	} else if e > tree.E {
		tree.Right = remove(tree.Right, e)
		return tree
	} else {
		//删除左子树为空
		if tree.Left == nil {
			right := tree.Right
			tree.Right = nil
			return right
		}
		//删除右子树为空
		if tree.Right == nil {
			left := tree.Left
			tree.Left = nil
			return left
		}
		//删除元素左右子树均不为空
		//找到待删除节点的最小节点,即待删除节点的右子树的最小节点
		//用这个节点代替删除节点,待删除左子树继续拼接
		successor := minimum(tree.Right)        //待删除节点的最小节点
		successor.Right = removemin(tree.Right) //删除操作
		successor.Left = tree.Left
		tree.Left = nil
		tree.Right = nil
		return successor
	}
}

/**        10
 *       /    \
		7     15
 *     / \    /
      2   8  11
 *     \   \  \
        3   9  12
 */
//removemin 递归删除最小值
func removemin(tree *Two_tree) *Two_tree {
	if tree.Left == nil {
		right := tree.Right
		tree.Right = nil
		return right
	}
	//使原右子树代替左子树
	tree.Left = removemin(tree.Left)
	return tree
}

//minimum 递归查询二分搜索树的最小元素
func minimum(tree *Two_tree) *Two_tree {
	if tree.Left == nil {
		return tree
	}
	return minimum(tree.Left)
}

//postorder 递归后续遍历
func postorder(tree *Two_tree) {
	if tree == nil {
		return
	}
	preorder(tree.Left)
	preorder(tree.Right)
	fmt.Println(tree.E)
}

//inorder 递归中序遍历
func inorder(tree *Two_tree) {
	if tree == nil {
		return
	}
	preorder(tree.Left)
	fmt.Println(tree.E)
	preorder(tree.Right)
}

//preorder 递归前序遍历
func preorder(tree *Two_tree) {
	if tree == nil {
		return
	}
	fmt.Println(tree.E)
	preorder(tree.Right)
	preorder(tree.Left)
}

//empty 递归判断
func empty(tree *Two_tree, E int) bool {
	if tree == nil {
		return false
	}
	if E == tree.E {
		return true
	} else if E < tree.E {
		return empty(tree.Left, E)
	} else if E > tree.E {
		return empty(tree.Right, E)
	}
	return false
}

//add 递归添加
func add(tree *Two_tree, E int) *Two_tree {
	//判断是否是根
	if tree == nil {
		size++
		tree = &Two_tree{E, nil, nil}
		return tree
	}

	//递归转化更小问题
	if E < tree.E {
		tree.Left = add(tree.Left, E)
	} else if E > tree.E {
		tree.Right = add(tree.Right, E)
	}
	return tree
}

 

 

 

 

 

   

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值