Scala实现二叉搜索树

RT。

package com.fetching.algorithm
/**
  * 二叉搜索树,即每一个节点,它的左孩子都不大于它,右孩子都不小于它
  * author:卧龙居
  */
class TreeNode{
  var data:Integer = 0
  var lchild:TreeNode = null
  var rchild:TreeNode = null
  var parent:TreeNode = null

  def this(data:Integer){
    this()
    this.data = data
  }
}

object BinarySearchTree {
    //向二叉搜索树中插入节点
    def addTreeNode(root:TreeNode,data:Integer):TreeNode={
      if(root == null){
        new TreeNode(data)
      }else{
        var preNode:TreeNode = null
        var curNode:TreeNode = root

        while(curNode != null){
          if(data <= curNode.data){
            preNode = curNode
            curNode = preNode.lchild
            if(curNode == null){
              preNode.lchild = new TreeNode(data)
              preNode.lchild.parent = preNode
            }
          }else{
            preNode = curNode
            curNode = preNode.rchild
            if(curNode == null){
              preNode.rchild = new TreeNode(data)
              preNode.rchild.parent = preNode
            }
          }
        }
        root
      }
    }

    //递归先序遍历二叉搜索树
    def preOrder(root:TreeNode): Unit ={
      if(root != null){
        println(root.data)
        preOrder(root.lchild)
        preOrder(root.rchild)
      }
    }

    //中序遍历二叉搜索树,则相当于排序输出
    def inOrder(root:TreeNode): Unit = {
      if(root != null){
        inOrder(root.lchild)
        println(root.data)
        inOrder(root.rchild)
      }
    }

    //取得以某个节点为根的子树中的最小节点
    def getMinNode(root:TreeNode):TreeNode = {
      if(root.lchild == null){
        root
      }else{
        getMinNode(root.lchild)
      }
    }

    //取得以某个节点为根的子树的最大节点
    def getMaxNode(root:TreeNode):TreeNode = {
      if(root.rchild == null){
        root
      }else{
        getMaxNode(root.rchild)
      }
    }

    //根据data返回树节点
    def search(root:TreeNode,data:Integer):TreeNode={
      if(root.data == data){
        root
      }else if(root == null){
        null
      }else{
        if(data <= root.data){
          search(root.lchild,data)
        }else{
          search(root.rchild,data)
        }
      }
    }

    //一个节点的后继,即是搜索树中大于该节点的最小节点
    def successor(root:TreeNode,curNodeVal:TreeNode):TreeNode = {
      var curNode:TreeNode = curNodeVal
      if(curNode.rchild != null){
        //如果此节点有右子树,则后继为其右子树中的最小节点
        getMinNode(curNode.rchild)
      }else{
        //如果节点没有右子树,则后继为从此节点开始向上遍历的第一个以它为左子树的节点
        var curParent:TreeNode = curNode.parent
        while (curParent != null && curParent.rchild == curNode){
          curNode = curNode.parent
          curParent = curNode.parent
        }
        curParent
      }
    }

    //删除节点
    def deleteTreeNode(root:TreeNode,curNodeData:Integer):TreeNode={
      val curNode:TreeNode = search(root,curNodeData)
      if(curNode != null){
        //如果节点没有左右孩子,则直接将自己的父节点的孩子置为null即可
        if(curNode.lchild == null && curNode.rchild == null){
          if(curNode == curNode.parent.lchild){
            curNode.parent.lchild = null
          }else{
            curNode.parent.rchild = null
          }
          root
        }else if(curNode.lchild == null || curNode.rchild == null){
          //如果节点只有一颗子树,则直接将它的子树加到父节点上
          if(curNode == curNode.parent.lchild){
            if(curNode.lchild != null){
              curNode.lchild.parent = curNode.parent
              curNode.parent.lchild = curNode.lchild
            }else{
              curNode.rchild.parent = curNode.parent
              curNode.parent.lchild = curNode.rchild
            }
          }else{
            if(curNode.lchild != null){
              curNode.lchild.parent = curNode.parent
              curNode.parent.rchild = curNode.lchild
            }else{
              curNode.rchild.parent = curNode.parent
              curNode.parent.rchild = curNode.rchild
            }
          }
          root
        }else{
          //如果节点左右子树均有,则需要求出节点的后继节点
          //可以证明,此后继节点是没有左孩子的(如果它有左孩子,则不会成为大于目标节点的最小节点)
          var successorNode = successor(root,curNode)
          if(successorNode == curNode.rchild){
            //如果后继节点为待删除节点的右孩子
            //则用后继节点取代待删除节点
            successorNode.lchild = curNode.lchild
            if(curNode == curNode.parent.lchild){
              successorNode.parent = curNode.parent
              curNode.parent.lchild = successorNode
            }else{
              successorNode.parent = curNode.parent
              curNode.parent.rchild = successorNode
            }
            root
          }else{
            //如果后继节点不为待删除节点的右孩子,则它肯定在待删除节点右孩子的左子树中
            //1.将[后继节点]的右孩子设为[后继节点]父节点的左孩子
            //2.将待删除节点的右子树设为[后继节点]的右子树
            //3.将待删除节点的左子树设为[后继节点]的左子树
            //4.将[后继节点]设置为待删除节点父节点的孩子
            if(successorNode.rchild != null) {
              successorNode.rchild.parent = successorNode.parent
              successorNode.parent.lchild = successorNode.rchild
            }else{
              successorNode.parent.lchild = null
            }

            curNode.rchild.parent = successorNode
            successorNode.rchild = curNode.rchild
            curNode.lchild.parent = successorNode
            successorNode.lchild = curNode.lchild
            if(curNode == curNode.parent.lchild){
              successorNode.parent = curNode.parent
              curNode.parent.lchild = successorNode
            }else{
              successorNode.parent = curNode.parent
              curNode.parent.rchild = successorNode
            }

            root
          }
        }
      }else{
        null
      }
    }

    def main(args:Array[String]):Unit = {
      val datas = Array(1,2,10,6,8,7,9)
      var root:TreeNode = null
      for(item <- datas){
        root = addTreeNode(root,item)
      }
      println("create binarysearch tree complete")

      //新增一个节点
      addTreeNode(root,4)

      println("**************pre order********************")
      preOrder(root)
      println("**************pre order********************")

      println("**************in order********************")
      inOrder(root)
      println("**************in order********************")

      println("min node:"+getMinNode(root).data)
      println("max node:"+getMaxNode(root).data)
      println("cur node:"+search(root,4).data)

      //删除节点
      root = deleteTreeNode(root,6)
      println("**************pre order********************")
      preOrder(root)
      println("**************pre order********************")
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值