二叉树 前序/中序/后序/层序遍历 二叉搜索树插入/查找/删除实现

1. LinkedNode.go

package study

import (
	"container/list"
	"fmt"
	"math"
)

//MyStack used for Pre/In/Post order traverse
type MyStack struct {
	list *list.List
}

//Push ...
func (stack *MyStack) Push(elem interface{}) {
	stack.list.PushBack(elem)
}

//Pop from back
func (stack *MyStack) Pop() interface{} {
	if elem := stack.list.Back(); elem != nil {
		stack.list.Remove(elem)
		return elem.Value
	}
	return nil
}

//Len ...
func (stack *MyStack) Len() int {
	return stack.list.Len()
}

//Empty ...
func (stack *MyStack) Empty() bool {
	return stack.list.Len() == 0
}

//MyQueue used for level traverse
type MyQueue struct {
	list *list.List
}

//Push ...
func (queue *MyQueue) Push(elem interface{}) {
	queue.list.PushBack(elem)
}

//Pop from front
func (queue *MyQueue) Pop() interface{} {
	if elem := queue.list.Front(); elem != nil {
		queue.list.Remove(elem)
		return elem.Value
	}
	return nil
}

//Node ...
type Node struct {
	data        interface{}
	left, right *Node
}

//NewNode ...
func NewNode(data interface{}) *Node {
	return &Node{data: data}
}

//String ...
func (node *Node) String() string {
	return fmt.Sprintf("v:%+v, left:%+v, right:%+v", node.data, node.left, node.right)
}

//SetLeftNode ...
func (node *Node) SetLeftNode(l *Node) {
	if node == nil {
		return
	}
	node.left = l
}

//SetRightNode ...
func (node *Node) SetRightNode(r *Node) {
	if node == nil {
		return
	}
	node.right = r
}

//GetLeftNode ...
func (node *Node) GetLeftNode() *Node {
	if node == nil {
		return nil
	}
	return node.left
}

//GetRightNode ...
func (node *Node) GetRightNode() *Node {
	if node == nil {
		return nil
	}
	return node.right
}

//PreOrderTraverse 前序遍历
func (node *Node) PreOrderTraverse() {
	if node == nil {
		return
	}
	fmt.Print(node.data, " ")
	node.left.PreOrderTraverse()
	node.right.PreOrderTraverse()
}

//PreOrderTraverseByStack 前序遍历
//前序遍历的思路是通过栈,将右子树先行压栈,然后左子树压栈
func (node *Node) PreOrderTraverseByStack() {
	if node == nil {
		return
	}

	stack := MyStack{list: list.New()}
	stack.Push(node)

	for !stack.Empty() {
		nd := stack.Pop().(*Node)
		fmt.Print(nd.data, " ")

		if nd.right != nil {
			stack.Push(nd.right)
		}

		if nd.left != nil {
			stack.Push(nd.left)
		}
	}

}

//InOrderTraverse 中序遍历
func (node *Node) InOrderTraverse() {
	if node == nil {
		return
	}
	node.left.InOrderTraverse()
	fmt.Print(node.data, " ")
	node.right.InOrderTraverse()
}

//InOrderTraverseByStack 中序遍历
// 先将左子树压栈,直到最左边得左子树为空,然后左子树出栈,打印,返回上一层父节点,然后右子树
func (node *Node) InOrderTraverseByStack() {
	if node == nil {
		return
	}

	stack := MyStack{list: list.New()}
	current := node
	for !stack.Empty() || current != nil {
		if current != nil {
			stack.Push(current)
			current = current.left
		} else {
			current = stack.Pop().(*Node)
			fmt.Print(current.data, " ")
			current = current.right
		}
	}
}

//PostOrderTraverse 后序遍历
func (node *Node) PostOrderTraverse() {
	if node == nil {
		return
	}
	node.left.PostOrderTraverse()
	node.right.PostOrderTraverse()
	fmt.Print(node.data, " ")
}

//PostOrderTraverseByStack 后序遍历
//遍历顺序:左-右-根
//stack1 压出栈顺序: 根压->根出->根左子入->根右子入->根右子出->根左子出
//stack2 压栈顺序: 根->右->左, 出栈顺序: 左-右-根
func (node *Node) PostOrderTraverseByStack() {
	if node == nil {
		return
	}

	stack1, stack2 := MyStack{list: list.New()}, MyStack{list: list.New()}
	stack1.Push(node)

	for !stack1.Empty() {
		nd := stack1.Pop().(*Node)
		stack2.Push(nd)

		if nd.left != nil {
			stack1.Push(nd.left)
		}

		if nd.right != nil {
			stack1.Push(nd.right)
		}
	}

	for !stack2.Empty() {
		n := stack2.Pop().(*Node)
		fmt.Print(n.data, " ")
	}
}

//LevelTraverse 层序遍历
//借助队列实现,入对顺序:根->左子->右子  出队顺序: 根->左子->右子
func (node *Node) LevelTraverse() {
	if node == nil {
		return
	}
	var nlast *Node

	last := node
	level := 1

	queue := MyQueue{list: list.New()}
	queue.Push(node)

	fmt.Println(fmt.Sprintf("-----this is %d level-----", level))
	for queue.list.Len() > 0 {
		nd := queue.Pop().(*Node)

		if nd.left != nil {
			queue.Push(nd.left)
			nlast = nd.left
		}

		if nd.right != nil {
			queue.Push(nd.right)
			nlast = nd.right
		}
		fmt.Print(nd.data, " ")

		if last == nd {
			last = nlast
			level++
			fmt.Println()
			fmt.Println(fmt.Sprintf("-----this is %d level-----", level))
		}
	}
}

//Depth get tree depth
func (node *Node) Depth() int {
	if node == nil {
		return 0
	}
	left := node.left.Depth() + 1
	right := node.right.Depth() + 1

	return int(math.Max(float64(left), float64(right)))
}

//DepthByLevelTraverse ...
func (node *Node) DepthByLevelTraverse() int {
	if node == nil {
		return 0
	} else if node.left == nil && node.right == nil {
		return 1
	} else {
		depth := node.DepthByLevelT()
		return depth
	}
}

//DepthByLevelT ...
func (node *Node) DepthByLevelT() int {
	queue := list.New()
	queue.PushBack(node)

	maxDepth := 0
	for {
		len := queue.Len()
		if len == 0 {
			break
		}
		for i := 0; i < len; i++ { //遍历每层结点,然后maxDepth+1
			front := queue.Front()
			nd := (front.Value).(*Node)
			queue.Remove(front)

			if nd.left != nil {
				queue.PushBack(nd.left)
			}

			if nd.right != nil {
				queue.PushBack(nd.right)
			}
		}
		maxDepth++
	}
	return maxDepth
}

2.ArrayNode.go

package study

import "fmt"

//ArrayStack ...
type ArrayStack struct {
	data []interface{}
	//栈顶指针
	top int
}

//NewArrayStack for initial
func NewArrayStack() *ArrayStack {
	return &ArrayStack{
		data: make([]interface{}, 0, 32),
		top:  -1,
	}
}

//IsEmpty for check if stack is empty
func (stack *ArrayStack) IsEmpty() bool {
	if stack.top < 0 || stack == nil {
		return true
	}
	return false
}

//Push for push data
func (stack *ArrayStack) Push(v interface{}) {
	if stack == nil {
		return
	}
	if stack.top < 0 {
		stack.top = 0
	} else {
		stack.top++
	}
	if stack.top > len(stack.data)-1 {
		stack.data = append(stack.data, v)
	} else {
		stack.data[stack.top] = v
	}
}

//Pop for read data
func (stack *ArrayStack) Pop() interface{} {
	if stack.IsEmpty() || stack == nil {
		return nil
	}
	v := stack.data[stack.top]
	stack.top--
	return v
}

//Top for read top data
func (stack *ArrayStack) Top() interface{} {
	if stack.IsEmpty() || stack == nil {
		return nil
	}
	return stack.data[stack.top]
}

//Flush is for clear data
func (stack *ArrayStack) Flush() {
	if stack.IsEmpty() || stack == nil {
		return
	}
	stack.top = -1
	stack.data = make([]interface{}, 0, 32)
	fmt.Println("Flush success")
}

//Print ...
func (stack *ArrayStack) Print() {
	if stack.IsEmpty() || stack == nil {
		return
	}
	for i := 0; i <= stack.top; i++ {
		fmt.Printf("The %d data is %v\n", i, stack.data[i])
	}
}

//PreOrderTraverseByArray ...
func (stack *ArrayStack) PreOrderTraverseByArray(rootIndex int) {
	if rootIndex > stack.top {
		return
	}

	fmt.Print(stack.data[rootIndex], " ")
	stack.PreOrderTraverseByArray(rootIndex*2 + 1)
	stack.PreOrderTraverseByArray(rootIndex*2 + 2)
}

//InOrderTraverseByArray ...
func (stack *ArrayStack) InOrderTraverseByArray(rootIndex int) {
	if rootIndex > stack.top {
		return
	}
	stack.InOrderTraverseByArray(rootIndex*2 + 1)
	fmt.Print(stack.data[rootIndex], " ")
	stack.InOrderTraverseByArray(rootIndex*2 + 2)
}

//PostOrderTraverseByArray ...
func (stack *ArrayStack) PostOrderTraverseByArray(rootIndex int) {
	if rootIndex > stack.top {
		return
	}
	stack.PostOrderTraverseByArray(rootIndex*2 + 1)
	stack.PostOrderTraverseByArray(rootIndex*2 + 2)
	fmt.Print(stack.data[rootIndex], " ")
}

3.BinarySearchTree.go

package study

import "fmt"

//BSTree named binary search tree
type BSTree struct {
	*Node
	comepareFunc func(v, nodeV interface{}) int
}

//NewBSTree ...
func NewBSTree(rootV interface{}, comepareFunc func(v, nodeV interface{}) int) *BSTree {
	return &BSTree{Node: NewNode(rootV), comepareFunc: comepareFunc}
}

var CompareFunc = func(v, nodeV interface{}) int {
	vInt := v.(int)
	nodeVInt := nodeV.(int)

	if vInt > nodeVInt {
		return 1
	} else if vInt < nodeVInt {
		return -1
	}
	return 0
}

//Insert ...
func (bst *BSTree) Insert(v interface{}) bool {
	p := bst.Node

	for p != nil {
		comepareResult := bst.comepareFunc(v, p.data)
		if comepareResult == 0 {
			return false
		} else if comepareResult > 0 {
			if nil == p.right {
				p.right = NewNode(v)
				return true
			}
			p = p.right
		} else if comepareResult < 0 {
			if nil == p.left {
				p.left = NewNode(v)
				return true
			}
			p = p.left
		}
	}
	return false
}

//Find ...
func (bst *BSTree) Find(v interface{}) *Node {
	p := bst.Node

	for p != nil {
		comepareResult := bst.comepareFunc(v, p.data)
		if comepareResult == 0 {
			return p
		} else if comepareResult > 0 {
			p = p.right
		} else if comepareResult < 0 {
			p = p.left
		}
	}
	return nil
}

//Delete ...
func (bst *BSTree) Delete(v interface{}) bool {
	p := bst.Node
	var pp *Node //p的父节点
	for p != nil && bst.comepareFunc(v, p.data) != 0 {
		pp = p
		if bst.comepareFunc(v, p.data) > 0 {
			p = p.right
		} else {
			p = p.left
		}
	}
	if p == nil { //没有发现待删除的node
		fmt.Println("Not found")
		return false
	}

	//待删除的节点,有左右子树,此时应该把右子树中最小的节点替换p,把最小节点从右子树中删除,
	//最小节点可能没有左孩子,但是有右孩子,所以要结合最下面看
	if p.left != nil && p.right != nil {
		minP := p.right
		minPP := p //minPP表示minP的父节点
		for minP.left != nil {
			minPP = minP
			minP = minP.left
		}

		p.data = minP.data //将 minP 的数据替换到 p 中
		p = minP           //删除p节点变为删除minP节点操作,这一点不好理解,要结合后面看
		pp = minPP
	}

	//删除节点是叶子节点或者仅有一个子节点
	var child *Node //p的孩子
	if p.left != nil {
		child = p.left
	} else if p.right != nil {
		child = p.right
	} else {
		child = nil
	}

	if pp == nil { //删除的是根节点,
		bst.Node = child
	} else if pp.left == p {
		pp.left = child
	} else if pp.right == p {
		pp.right = child
	}
	return true
}

//MinNode ...
func (bst *BSTree) MinNode() *Node {
	if bst == nil {
		return nil
	}
	node := bst.Node
	for node.left != nil {
		node = node.left
	}
	fmt.Println("min node is ", node.data)
	return node
}

//MaxNode ...
func (bst *BSTree) MaxNode() *Node {
	if bst == nil {
		return nil
	}
	node := bst.Node
	for node.right != nil {
		node = node.right
	}
	fmt.Println("max node is ", node.data)
	return node
}

 

3.main.go

package main

import (
	"fmt"
	"tree/study"
)

func main() {

	//ArrayNode Operate
	fmt.Println("\nTreeNode base Array")
	stack := study.NewArrayStack()
	isempty := stack.IsEmpty()

	fmt.Println("stack is empty:", isempty)
	stack.Push("0")
	stack.Push("1")
	stack.Push("2")
	stack.Push("3")
	stack.Push("4")
	stack.Push("5")
	stack.Push("6")
	stack.Print()

	fmt.Println("PreOrderTraverseByArray")
	stack.PreOrderTraverseByArray(0)
	fmt.Println("\nInOrderTraverseByArray")
	stack.InOrderTraverseByArray(0)
	fmt.Println("\nPostOrderTraverseByArray")
	stack.PostOrderTraverseByArray(0)

	//TreeNode Traverse
	fmt.Println("\n------------TreeNode base Link---------------")

	lNode := study.NewNode("1")
	rNode := study.NewNode("2")

	llNode := study.NewNode("3")
	lrNode := study.NewNode("4")

	rlNode := study.NewNode("5")
	rrNode := study.NewNode("6")

	treeNode := study.NewNode("root")
	treeNode.SetLeftNode(lNode)
	treeNode.SetRightNode(rNode)

	treeNode.GetLeftNode().SetLeftNode(llNode)
	treeNode.GetLeftNode().SetRightNode(lrNode)

	treeNode.GetRightNode().SetLeftNode(rlNode)
	treeNode.GetRightNode().SetRightNode(rrNode)

	fmt.Println("PreOrderTraverse")
	treeNode.PreOrderTraverse()
	fmt.Println("\nPreOrderTraverseByStack")
	treeNode.PreOrderTraverseByStack()

	fmt.Println("\nInOrderTraverse")
	treeNode.InOrderTraverse()
	fmt.Println("\nInOrderTraverseByStack")
	treeNode.InOrderTraverseByStack()

	fmt.Println("\nPostOrderTraverse")
	treeNode.PostOrderTraverse()
	fmt.Println("\nPostOrderTraverseByStack")
	treeNode.PostOrderTraverseByStack()

	fmt.Println("\nLevelTraverse")
	treeNode.LevelTraverse()

	//BST
	fmt.Println("\n------------BST base Link---------------")

	bst := study.NewBSTree(4, study.CompareFunc)
	bst.Insert(1)
	bst.Insert(2)
	bst.Insert(3)
	bst.Insert(4)
	bst.Insert(5)
	bst.Insert(6)

	bst.MaxNode()
	bst.MinNode()

	fmt.Println("\nLevelTraverse")
	bst.Node.LevelTraverse()

	fmt.Println("\nfind 3")
	node := bst.Find(3)
	fmt.Println(node)

	fmt.Println("Delete 1")
	bst.Delete(1)
	node = bst.Find(1)
	fmt.Println(node)
	fmt.Println("\nLevelTraverse")
	bst.Node.LevelTraverse()

	fmt.Println("Delete 4")
	bst.Delete(4)
	node = bst.Find(4)
	fmt.Println(node)
	fmt.Println("LevelTraverse")
	bst.Node.LevelTraverse()

	depth := bst.Node.Depth()
	fmt.Println("Tree depth is ", depth)

	depthBT := bst.Node.DepthByLevelTraverse()
	fmt.Println("Tree depth by level traverse is ", depthBT)
}

3.输出:

TreeNode base Array
stack is empty: true
The 0 data is 0
The 1 data is 1
The 2 data is 2
The 3 data is 3
The 4 data is 4
The 5 data is 5
The 6 data is 6
PreOrderTraverseByArray
0 1 3 4 2 5 6 
InOrderTraverseByArray
3 1 4 0 5 2 6 
PostOrderTraverseByArray
3 4 1 5 6 2 0 
------------TreeNode base Link---------------
PreOrderTraverse
root 1 3 4 2 5 6 
PreOrderTraverseByStack
root 1 3 4 2 5 6 
InOrderTraverse
3 1 4 root 5 2 6 
InOrderTraverseByStack
3 1 4 root 5 2 6 
PostOrderTraverse
3 4 1 5 6 2 root 
PostOrderTraverseByStack
3 4 1 5 6 2 root 
LevelTraverse
-----this is 1 level-----
root 
-----this is 2 level-----
1 2 3 4 5 6 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值