二叉樹

爱跑步的乌龟發表於2024-07-20
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 //計算節點數量
}

相關文章