1. 程式人生 > 實用技巧 >11-二叉樹排序樹-Scala實現

11-二叉樹排序樹-Scala實現

二叉排序樹的建立、遍歷、刪除

package com.atguigu.datastructures.binarytree

/**
  * 二叉排序樹的建立和遍歷
  * 刪除,1.刪除葉子節點,因為二叉排序樹是單向的,需要在刪除時,找到刪除節點的父節點
  *      2.先檢索要刪除節點,如果沒有找到就退出;反之,找到該節點的父節點
  *      3.刪除該節點
  */
//Array(7,3,10,12,5,1,9)
object BinarySortTreeDemo {
  def main(args: Array[String]): Unit = {
    val arr=Array(7,3,10)
    val binarySortTree = new BinarySortTree
    for (elem <- arr) {
      binarySortTree.add(new Node(elem))
    }
    binarySortTree.infixOrder()
    //刪除
    binarySortTree.delNode(10)
    binarySortTree.delNode(3)
    println("刪除後")
    binarySortTree.infixOrder()

  }

}

//定義節點
class Node(var value:Int){
  var left:Node = null
  var right:Node = null

  //根據值來查詢某個節點
  def search(value:Int):Node={
    //先判斷當前節點是否是要刪除的節點
    if(value == this.value){
      return this
    }else if(value < this.value){//向左遞迴查詢
      if(this.left == null){
        return null
      }else{
        return this.left.search(value)
      }
    }else{
      if (this.right == null){
         null
      }else{//否則向右遞迴查詢
        this.right.search(value)
      }
    }

  }



  //找某個節點的父節點
  def searchParent(value:Int):Node={
    //思路
    //1.先判斷當前節點的左子節點或者右子節點是否是這個值
    if((this.left != null && this.left.value == value) ||
      (this.right != null && this.right.value == value)
    ){
       this
    }else{
      if (this.left != null && value < this.value){//說明要向左邊去遞迴查詢
          this.left.searchParent(value)
      }else if (this.right != null && value > this.value){//說明要向左邊去遞迴查詢
        this.right.searchParent(value)
      }else {
        null
      }
    }
  }
  //新增方法
  def add(node: Node): Unit ={
    if (node == null){
      return
    }
    //如果要插入節點的值,小於當前節點的值,則可以處理
    if (node.value < this.value){
      if (this.left == null){//說明該節點下沒有左子節點
        this.left = node
      }else{
        //遞迴的進行插入
        this.left.add(node)
      }
    }else{ //如果要插入節點的值,不小於當前節點的值,則可以處理
      if (this.right == null){
        this.right = node
      }else{
        //遞迴進行插入
        this.right.add(node)
      }
    }
  }
  def infixOrder(): Unit ={
    if (this.left != null){
      this.left.infixOrder()
    }
    printf("節點資訊 no=%d \n",value)
    if (this.right != null){
      this.right.infixOrder()
    }
  }
}

//定義二叉排序樹
class BinarySortTree{
  var root:Node = null

  //刪除某個右子樹的最小值的節點,並返回最小值
  def delRightTreeMin(node: Node): Int ={
    var target = node
    //使用while迴圈,找到右子樹的最小值
    while (target.left != null){
      target = target.left
    }
    val minValue = target.value
    delNode(minValue)
    minValue
  }
  //查詢節點
  def search(value:Int):Node={
    if (root != null){
      root.search(value)
    }else{
      null
    }
  }
  //查詢父節點
  def searchParent(value:Int):Node={
    if (root != null){
      root.searchParent(value)
    }else{
      null
    }
  }

  //刪除節點
  //1.先考慮的是葉子節點
  def delNode(value:Int): Unit ={
    if (root == null){//如果是空樹,就不刪除
      null
    }
    //先看有沒有要刪除的節點
    var targetNode = search(value)
    if (targetNode == null){
      return
    }
    var parentNode = searchParent(value)
    if (parentNode==null){
      root = null
      return
    }
    //1.先考慮的是葉子節點
    if (targetNode.left == null && targetNode.right == null){
      //判斷刪除的節點parentNode的左子節點,還是右子節點
      if (parentNode.left != null && parentNode.left.value == value){
        parentNode.left = null
      }else{
        parentNode.right = null
      }
    }else if(targetNode.left != null && targetNode.right != null){
      val value: Int = delRightTreeMin(targetNode.right)
      targetNode.value = value
      //兩個子節點
    }else{
      //targetNode只有一個子節點
      //判斷是左子節點還是右子節點
      if (targetNode.left !=null){
        if (parentNode.left.value == value){
          parentNode.left = targetNode.left
        }else{
          parentNode.right = targetNode.left
        }
      }else{
        //判斷targetNode是parentNode的左還是右
        if (parentNode.left.value == value){
          parentNode.left = targetNode.right
        }else{
          parentNode.right = targetNode.right
        }
      }
    }
  }

  def add(node: Node): Unit ={
    if (root == null){
      root = node
    }else{
      root.add(node)
    }
  }
  def infixOrder(): Unit ={
    if (root != null){
      root.infixOrder()
    }else{
      println("當前樹為空")
    }
  }

}