package main import ( "bytes" "container/list" "fmt" "strconv" ) type Node struct { Data int //資料 Left *Node //指向左邊節點 Right *Node //指向右邊節點 } type BinaryTree struct { Root *Node //根節點 Size int //資料的數量 } //新建一個二叉樹 func NewBinaryTree() *BinaryTree { bst := &BinaryTree{} bst.Size = 0 bst.Root = nil return bst } //獲取二叉樹大小 func (bst *BinaryTree) GetSize() int { return bst.Size } //判斷是否為空 func (bst *BinaryTree) IsEmpty() bool { return bst.Size == 0 } //根節點插入 func (bst *BinaryTree) Add(data int) { bst.Root = bst.add(bst.Root, data) } //插入節點 func (bst *BinaryTree) add(n *Node, data int) *Node { if n == nil { bst.Size++ //return &Node{Data:data} return &Node{data, nil, nil} } if data < n.Data { n.Left = bst.add(n.Left, data) //比我小,左邊 } else if data > n.Data { n.Right = bst.add(n.Right, data) //比我小,左邊 } return n } //判斷資料是否存在 func (bst *BinaryTree) Isin(data int) bool { return bst.isin(bst.Root, data) //從根節點開始查詢 } func (bst *BinaryTree) isin(n *Node, data int) bool { if n == nil { return false //樹是空樹,找不到 } if data == n.Data { return true } else if data < n.Data { return bst.isin(n.Left, data) } else { return bst.isin(n.Right, data) } } func (bst *BinaryTree) FindMax() int { if bst.Size == 0 { panic("二叉樹為空") } return bst.findmax(bst.Root).Data //取得最大 } func (bst *BinaryTree) findmax(n *Node) *Node { if n.Right == nil { return n } else { return bst.findmax(n.Right) } } func (bst *BinaryTree) FindMin() int { if bst.Size == 0 { panic("二叉樹為空") } return bst.findmin(bst.Root).Data //取得最大 } func (bst *BinaryTree) findmin(n *Node) *Node { if n.Left == nil { return n } else { return bst.findmin(n.Left) } } //前序遍歷 func (bst *BinaryTree) PreOrder() { bst.preorder(bst.Root) } func (bst *BinaryTree) PreOrderNoRecursion() []int { mybst := bst.Root //備份二叉樹 mystack := list.New() //生成一個棧 res := make([]int, 0) //生成陣列,容納中序的資料 for mybst != nil || mystack.Len() != 0 { for mybst != nil { res = append(res, mybst.Data) //壓入資料 mystack.PushBack(mybst) //首先左邊壓入棧中 mybst = mybst.Left } if mystack.Len() != 0 { v := mystack.Back() //挨個取出節點 mybst = v.Value.(*Node) //例項化 //res=append(res,mybst.Data)//壓入資料 mybst = mybst.Right //追加 mystack.Remove(v) //刪除 } } return res } func (bst *BinaryTree) preorder(node *Node) { if node == nil { return } fmt.Println(node.Data) bst.preorder(node.Left) bst.preorder(node.Right) } //中序遍歷 func (bst *BinaryTree) InOrder() { bst.inorder(bst.Root) } func (bst *BinaryTree) InOrderNoRecursion() []int { mybst := bst.Root //備份二叉樹 mystack := list.New() //生成一個棧 res := make([]int, 0) //生成陣列,容納中序的資料 for mybst != nil || mystack.Len() != 0 { for mybst != nil { mystack.PushBack(mybst) //首先左邊壓入棧中 mybst = mybst.Left } if mystack.Len() != 0 { v := mystack.Back() //挨個取出節點 mybst = v.Value.(*Node) //例項化 res = append(res, mybst.Data) //壓入資料 mybst = mybst.Right //追加 mystack.Remove(v) //刪除 } } return res } //壓入資料 //for 棧不為空 // if else func (bst *BinaryTree) inorder(node *Node) { if node == nil { return } bst.inorder(node.Left) fmt.Println(node.Data) bst.inorder(node.Right) } //後序遍歷 func (bst *BinaryTree) PostOrder() { bst.postorder(bst.Root) } func (bst *BinaryTree) PostOrderNoRecursion() []int { mybst := bst.Root //備份二叉樹 mystack := list.New() //生成一個棧 res := make([]int, 0) //生成陣列,容納中序的資料 var PreVisited *Node //提前訪問的節點 for mybst != nil || mystack.Len() != 0 { for mybst != nil { mystack.PushBack(mybst) //首先左邊壓入棧中 mybst = mybst.Left //左邊 } v := mystack.Back() //取出節點 top := v.Value.(*Node) if (top.Left == nil && top.Right == nil) || (top.Right == nil && PreVisited == top.Left) || (PreVisited == top.Right) { res = append(res, top.Data) //壓入資料 PreVisited = top //記錄上一個節點 mystack.Remove(v) //處理完了在棧中刪除 } else { mybst = top.Right //右邊迴圈 } } return res } func (bst *BinaryTree) postorder(node *Node) { if node == nil { return } bst.postorder(node.Left) bst.postorder(node.Right) fmt.Println(node.Data) } func (bst *BinaryTree) String() string { var buffer bytes.Buffer //儲存字串 bst.GenerateBSTstring(bst.Root, 0, &buffer) //呼叫函式實現遍歷 return buffer.String() } func (bst *BinaryTree) GenerateBSTstring(node *Node, depth int, buffer *bytes.Buffer) { if node == nil { //buffer.WriteString(bst.GenerateDepthstring(depth)+"nil\n")//空節點 return } //寫入字串,儲存樹的深度 bst.GenerateBSTstring(node.Left, depth+1, buffer) buffer.WriteString(bst.GenerateDepthstring(depth) + strconv.Itoa(node.Data) + "\n") bst.GenerateBSTstring(node.Right, depth+1, buffer) } func (bst *BinaryTree) GenerateDepthstring(depth int) string { var buffer bytes.Buffer //儲存字串 for i := 0; i < depth; i++ { buffer.WriteString("--") //深度為0,1-- 2---- } return buffer.String() } //刪除最小 func (bst *BinaryTree) RemoveMin() int { ret := bst.FindMin() bst.Root = bst.removemin(bst.Root) return ret } func (bst *BinaryTree) removemin(n *Node) *Node { if n.Left == nil { //刪除 rightNode := n.Right //備份右邊節點 bst.Size-- //刪除 return rightNode } n.Left = bst.removemin(n.Left) return n } //刪除最大 func (bst *BinaryTree) RemoveMax() int { ret := bst.FindMax() bst.Root = bst.removemax(bst.Root) return ret } func (bst *BinaryTree) removemax(n *Node) *Node { if n.Right == nil { //刪除 leftNode := n.Left //備份右邊節點 bst.Size-- //刪除 return leftNode } n.Right = bst.removemax(n.Right) return n } func (bst *BinaryTree) Remove(data int) { bst.Root = bst.remove(bst.Root, data) //刪除資料 } func (bst *BinaryTree) remove(n *Node, data int) *Node { if n == nil { return nil //節點為空,不需要幹活 } if data < n.Data { n.Left = bst.remove(n.Left, data) //遞迴左邊 return n } else if data > n.Data { n.Right = bst.remove(n.Right, data) //遞迴右邊 return n } else { //處理左邊為空 if n.Left == nil { rightNode := n.Right //備份右邊節點 n.Right = nil bst.Size-- //刪除 return rightNode } //處理右邊為空 if n.Right == nil { leftNode := n.Left //備份右邊節點 n.Left = nil //處理節點返回 bst.Size-- //刪除 return leftNode } //左右節點都不為空 oknode := bst.findmin(n.Right) //找出比我小的節點頂替我 oknode.Right = bst.removemin(n.Right) //6,7 oknode.Left = n.Left //刪除 n.Left = nil //刪除的清空 n.Right = nil return oknode //實現刪除 } } func (bst *BinaryTree) Levelshow() { bst.levelshow(bst.Root) } func (bst *BinaryTree) levelshow(n *Node) { myqueue := list.New() //新建一個list模擬佇列 myqueue.PushBack(n) //後面壓入資料 for myqueue.Len() > 0 { left := myqueue.Front() //前面取出資料 right := left.Value myqueue.Remove(left) //刪除 if v, ok := right.(*Node); ok && v != nil { fmt.Println(v.Data) //列印資料 myqueue.PushBack(v.Left) myqueue.PushBack(v.Right) } } } func (bst *BinaryTree) Stackshow(n *Node) { myqueue := list.New() //新建一個list模擬佇列 myqueue.PushBack(n) //後面壓入資料 for myqueue.Len() > 0 { left := myqueue.Back() //前面取出資料 ,此時是棧 right := left.Value myqueue.Remove(left) //刪除 if v, ok := right.(*Node); ok && v != nil { fmt.Println(v.Data) //列印資料 myqueue.PushBack(v.Left) myqueue.PushBack(v.Right) } } } func (bst *BinaryTree) FindlowerstAncestor(root *Node, nodea *Node, nodeb *Node) *Node { if root == nil { return nil } if root == nodea || root == nodeb { return root //有一個節點是根節點, } left := bst.FindlowerstAncestor(root.Left, nodea, nodeb) //遞迴查詢 right := bst.FindlowerstAncestor(root.Right, nodea, nodeb) //遞迴查詢 if left != nil && right != nil { return root } if left != nil { return left } else { return right } } func (bst *BinaryTree) GetDepth(root *Node) int { if root == nil { return 0 } if root.Right == nil && root.Left == nil { return 1 } lengthleft := bst.GetDepth(root.Left) rightlength := bst.GetDepth(root.Right) if lengthleft > rightlength { return lengthleft + 1 } else { return rightlength + 1 } } func (bst *BinaryTree) SumofTree(root *Node) int { if root == nil { return 0 } leftnum := bst.SumofTree(root.Left) rightnum := bst.SumofTree(root.Right) return leftnum + rightnum + 1 //計算節點數量 }