scala實現二叉排序樹的添加、刪除、查找、遍歷等操作

//二叉排序樹
//由數組轉爲二叉排序樹
//三種遍歷方式
//添加節點
//刪除節點
//查找節點
//查找父節點
class TreeNode(Value:Int){
    var value = Value
    var left:TreeNode = null
    var right:TreeNode = null
    
    def addItem(node:TreeNode):Unit={
        //添加元素
        //重複節點掛右側
        if (node == null) return 
        
        if (node.value < value){
            if (this.left == null) this.left = node
            else{
                this.left.addItem(node)
            } 
        } else{
            if (this.right == null) this.right = node
            else this.right.addItem(node)
        }
    }
    
    def preOrder():Unit = {
        //前序遍歷
        if (this == null) {
            return
        }
        println(this.value)
        if (this.left != null)
            this.left.preOrder()
        if (this.right != null)
            this.right.preOrder()
    }
    
    def inOrder():Unit = {
        //中序遍歷
        if (this == null){
            return
        }
        if (this.left != null)
            this.left.inOrder()
        println(this.value)
        if (this.right != null)
            this.right.inOrder()
    }
    
    def postOrder():Unit = {
        //後序遍歷
        if (this == null){
            return
        }
        if (this.left != null)
            this.left.postOrder()
        if (this.right != null)
            this.right.postOrder()
        println(this.value)
    }
    
    def searchPoint(Value:Int):TreeNode={
        //查找節點
        //從根節點開始找 this即爲根節點
        //類似二分查找
        val value = Value
        if (this == null) return null
        if (this.value == value) return this

        if (this.value > value){
            if (this.left != null)
            return this.left.searchPoint(value)
            else return null
        } else {
            if (this.right != null)
            return this.right.searchPoint(value)
            else return null
        }
    }
    
    
    def searchParent(Value:Int):TreeNode={
        //查找父節點
        val value = Value
        if (this == null) return null
        
        if (this.value == value) return null
        if (this.value > value){
            if (this.left != null){
                if (this.left.value == value) return this
                else this.left.searchParent(value)
            } else return null
        } else{
            if (this.right != null){
                if (this.right.value == value) return this
                else this.right.searchParent(value)
            } else return null
        }
    }
}


class BinarySortTree(){
     var root :TreeNode = null
    
    def addItem(node:TreeNode):Unit = {
        if (root == null){
            root = node
        } else{
            root.addItem(node)
        }
    }
    def preOrder(){
        //前序遍歷
        root.preOrder()
    }

    def inOrder(){
        //中序遍歷
        root.inOrder()
    }
    def postOrder(){
        //後序遍歷
        root.postOrder()
    }
    
    def searchPoint(Value:Int):TreeNode={
        //尋找某個點
        val value = Value
        if (root != null){
            return root.searchPoint(value)
        } else return null
    }
    
    def searchParent(Value:Int):TreeNode = {
        //尋找某個點的父節點
        val value = Value
        if (root != null){
            return root.searchParent(value)
        } else return null
    }
    
    def delRightTreeMin(node1:TreeNode,node2:TreeNode):Unit = {
        //node1 要刪除的節點  node2:要刪除的節點的右子樹
        //刪除右子樹最小值,並將該值賦值給右子樹的父節點
        var target = node2
        var flag = target
        
        //如果右子樹沒有左子樹,則說明該右子樹節點爲最小值,用該值來修改要刪除的節點,即完成了刪除,
        //將該右子樹的右節點掛在要刪除的節點的右節點,即完成了整個刪除步驟
        if(target.left == null){
            if (target.right != null){
                node1.value = target.value
                node1.right = target.right
                return
            }
        }
        
        //如果右子樹右左節點,則循環查找其左節點,最後一個左節點即爲最小值,仍如上述完成修改並將最小節點刪除
        while(target.left != null){
            flag = target
            target = target.left
        }
        var minValue = target.value
        node1.value = minValue
        flag.left = target.right
    }
    

    
    def delNode(Value:Int):Unit={
        //
        //刪除節點
        //節點可能有三種情況
        //0.考慮是否是根節點、是否存在該節點
        //1.節點爲葉子節點:找到並刪除即可
        //2.節點含有一個子節點:找到該節點的父節點,並把該節點的子節點掛到該節點的父節點
        //3.節點含有兩個子節點:找到該節點的父節點,並在該節點的右子樹中找到最小值,將該節點的值替換爲最小值,並刪除右子樹的最小值
        val value = Value
        if (root == null) return 
        var theNode = searchPoint(value)
        if (theNode == null){
            println("未找到該節點")
            return
        }
        
        if (theNode != null){
            var theParent = searchParent(value)
                
            if (theNode.left == null && theNode.right == null){
                //要刪節點爲葉子節點
                if (theParent == null){
                    //此時樹只有一個根
                    root = null
                    return
                }
                
                if (theParent.left != null && theParent.left.value == value) theParent.left = null
                else if (theParent.right != null && theParent.right.value == value) theParent.right = null
            }else if(theNode.left != null && theNode.right != null){
                //要刪節點有兩個左右子節點
                delRightTreeMin(theNode,theNode.right)
 

            } else{
                //要刪節點只有一個子節點
                if (theParent == null){
                    //要刪除的爲根節點,並且根節點只有一側有數據
                    if(theNode.left == null) {
                        root = theNode.right
                        return
                    } else {
                        root = theNode.left
                        return
                    }
                }
                
                //刪除的節點是左節點
                if (theParent.left != null && theParent.left.value == value){
                    if(theNode.left != null)
                        theParent.left = theNode.left
                    else theParent.left = theNode.right
                //刪除的節點是右節點
                } else if (theNode.left != null)
                        //刪除的節點左節點不爲空,則將該節點的左子樹掛在父節點的右子樹
                        theParent.right = theNode.left
                        //刪除的節點右節點不爲空,則將該節點的右子樹掛在父節點的右子樹
                    else theParent.right = theNode.right
            }
            
        }else {}
    }
}




var bst = new BinarySortTree()
val arr = Array(10,8,4,9,15,12,10,20,,17,20)
for (item <- arr){
    bst.addItem(new TreeNode(item))
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章