二叉树(Scala版本)

package datastructure

/**
 * 二叉树demo
 */
object BinaryTreeDemo {
  def main(args: Array[String]): Unit = {
    val root = new HeroNode(1, "宋江")
    val hero2 = new HeroNode(2, "吴用")
    val hero3 = new HeroNode(3, "卢俊义")
    val hero4 = new HeroNode(4, "武松")
    val hero5 = new HeroNode(5, "林冲")
    root.left = hero2
    root.right = hero3
    hero3.left = hero5
    hero3.right = hero4
    val tree = new BinaryTree
    tree.root = root
    println("---------------前序遍历-------------------")
    tree.perOrder()
    println("---------------中序遍历-------------------")
    tree.infixOrder()
    println("---------------后序遍历-------------------")
    tree.postOrder()
    println("---------------前序查找-------------------")
    val perOrderNode: HeroNode = tree.perOrderSearch(5)
    if (perOrderNode != null) {
      printf("找到了~ no = %d,name=%s\n", perOrderNode.no, perOrderNode.name)
    } else {
      println("没找到")
    }
    println("---------------中序查找-------------------")
    val infixOrderNode: HeroNode = tree.infixOrderSearch(5)
    if (infixOrderNode != null) {
      printf("找到了~ no = %d,name=%s\n", infixOrderNode.no, infixOrderNode.name)
    } else {
      println("没找到")
    }
    println("---------------后序查找-------------------")
    val postOrderNode: HeroNode = tree.postOrderSearch(5)
    if (postOrderNode != null) {
      printf("找到了~ no = %d,name=%s\n", postOrderNode.no, postOrderNode.name)
    } else {
      println("没找到")
    }
    println("---------------删除节点-------------------")
//    tree.delNode(5)
//    tree.delNode(3)
    tree.delNode(1)
    println("---------------前序遍历-------------------")
    tree.perOrder()

  }
}

class HeroNode(hNo: Int, hName: String) {
  val no = hNo
  var name = hName
  var left: HeroNode = null
  var right: HeroNode = null


  def delNode(no: Int): Unit = {
    if (this.left != null && this.left.no == no) {
      this.left = null
      return
    }
    if (this.right != null && this.right.no == no) {
      this.right = null
      return
    }
    if (this.left != null) {
      this.left.delNode(no)
    }
    if (this.right != null) {
      this.right.delNode(no)
    }

  }

  //前序遍历
  def preOrder(): Unit = {
    printf("当前节点 no = %d,name = %s\n", no, name)
    //递归调用
    if (this.left != null) {
      this.left.preOrder()
    }
    if (this.right != null) {
      this.right.preOrder()
    }
  }

  //前序查找
  def preOrderSearch(no: Int): HeroNode = {
    if (this.no == no) {
      return this
    }
    var resNode: HeroNode = null
    if (this.left != null) {
      resNode = this.left.preOrderSearch(no)
    }
    if (resNode != null) {
      return resNode
    }
    if (this.right != null) {
      resNode = this.right.preOrderSearch(no)
    }
    resNode
  }

  //中序遍历
  def infixOrder(): Unit = {
    //递归调用
    if (this.left != null) {
      this.left.infixOrder()
    }
    printf("当前节点 no = %d,name = %s\n", no, name)
    if (this.right != null) {
      this.right.infixOrder()
    }
  }

  def infixOrderSearch(no: Int): HeroNode = {
    var resNode: HeroNode = null

    if (this.left != null) {
      resNode = this.left.infixOrderSearch(no)
    }
    if (resNode != null) {
      return resNode
    }
    if (this.no == no) {
      return this
    }
    if (this.right != null) {
      resNode = this.right.infixOrderSearch(no)
    }
    resNode
  }

  def postOrder(): Unit = {
    //递归调用
    if (this.left != null) {
      this.left.postOrder()
    }
    if (this.right != null) {
      this.right.postOrder()
    }
    printf("当前节点 no = %d,name = %s\n", no, name)
  }

  def postOrderSearch(no: Int): HeroNode = {
    var resNode: HeroNode = null

    if (this.left != null) {
      resNode = this.left.postOrderSearch(no)
    }
    if (resNode != null) {
      return resNode
    }
    if (this.right != null) {
      resNode = this.right.postOrderSearch(no)
    }
    if (resNode != null) {
      return resNode
    }
    if (this.no == no) {
      return this
    }
    resNode
  }
}

class BinaryTree {
  var root: HeroNode = null

  def delNode(no: Int): Unit = {
    if(root != null){
      if(root.no == no){
        root = null
      }else{
        root.delNode(no)
      }
    }
  }

  def perOrderSearch(no: Int): HeroNode = {
    if (root != null) {
      root.preOrderSearch(no)
    } else {
      null
    }
  }

  def perOrder(): Unit = {
    if (root != null) {
      root.preOrder()
    } else {
      println("当前二叉树为空,不能遍历")
    }
  }

  def infixOrderSearch(no: Int): HeroNode = {
    if (root != null) {
      root.infixOrderSearch(no)
    } else {
      null
    }
  }

  def infixOrder(): Unit = {
    if (root != null) {
      root.infixOrder()
    } else {
      println("当前二叉树为空,不能遍历")
    }
  }

  def postOrderSearch(no: Int): HeroNode = {
    if (root != null) {
      root.postOrderSearch(no)
    } else {
      null
    }
  }

  def postOrder(): Unit = {
    if (root != null) {
      root.postOrder()
    } else {
      println("当前二叉树为空,不能遍历")
    }
  }
}

顺序二叉树



 顺序存储二叉树的特点:
1) 顺序二叉树通常只考虑完全二叉树
2) 第 n 个元素的左子节点为 2 * n + 1
3) 第 n 个元素的右子节点为 2 * n + 2
4) 第 n 个元素的父节点为 (n-1) / 2
n : 表示二叉树中的第几个元素(按 0 开始编号如图所示)



需求: 给你一个数组 Array(1,2,3,4,5,6,7),要求以二叉树前序遍历的方式进行遍历。 前序遍历的结果应当为
1,2,4,5,3,6,7
代码实现:
package com.atguigu.chapter18.binarytree
object ArrayTreeDemo {
def main(args: Array[String]): Unit = {
val arr = Array(1,2,3,4,5,6,7)
val arrayTree = new ArrayTree(arr)
//前序遍历我们的数组
arrayTree.preOrder() //1,2,4,5,3,6,7
}
}
/*
课后练习:请同学们完
成对数组以二叉树中序,
后序遍历方式的代码.
*/
class ArrayTree(val arr:Array[Int]) {
//对 preOrder 进行一个重载
def preOrder(): Unit = {this.preOrder(0)
}
def preOrder(index:Int): Unit = {
if (arr == null || arr.length == 0) {
println("数组为空,不能按照二叉树前序遍历")
}
println(arr(index))
//向左递归遍历
if ((index * 2 + 1) < arr.length){
preOrder(index * 2 + 1)
}
//向右边递归遍历
if ((index * 2 + 2) < arr.length){
preOrder(index * 2 + 2)
}
}
}
二叉树排序树

给你一个数组 (7, 3, 10, 12, 5, 1, 9),要求能够高效的完成对数组的查询和添加

二叉排序树:BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当
前节点的值小,右子节点的值比当前节点的值大。
特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点
比如针对前面的数组 (7, 3, 10, 12, 5, 1, 9) ,对应的二叉排序树为:

一个数组创建成对应的二叉排序树,并使用中序遍历二叉排序树,比如: 数组为 Array(7, 3, 10, 12, 5, 1, 9)
二叉排序树的删除
二叉排序树的删除情况比较复杂,有下面三种情况需要考虑
1) 删除叶子节点 (比如:2, 5, 9, 12)
2) 删除只有一颗子树的节点 (比如:1)
3) 删除有两颗子树的节点. (比如:7, 3,10 )
二叉排序树的代码实现
//Array(7, 3, 10, 12, 5, 1, 9) 做成一个二叉排序树
object BinarySortTreeDemo {
def main(args: Array[String]): Unit = {
//测试一把
val arr = Array(7, 3, 10, 12, 5, 1, 9, 2)
//创建一颗二叉排序树
val binarySortTree = new BinarySortTree
for (item <- arr) {
binarySortTree.add(new Node(item))
}
//遍历二叉排序树
binarySortTree.infixOrder() // 1,3,5,7,9,10,12
//删除
// binarySortTree.delNode(2)
// binarySortTree.delNode(5)
// binarySortTree.delNode(9)
// binarySortTree.delNode(12)
binarySortTree.delNode(10)
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) {
return null
} else { //递归向右子树查找
return 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)) {
return this
} else {
if (this.left != null && value < this.value) { //说明需要向左边去递归查找
return this.left.searchParent(value)
} else if (this.right != null && value > this.value) { //说明需要向右边去递归查找
return 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("节点信息 value=%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)
return minValue
}
//查找节点
def search(value: Int): Node = {
if (root != null) {
return root.search(value)
} else {
return null
}
}
//查找父节点的方法
def searchParent(value: Int): Node = {
if (root != null) {
return root.searchParent(value)
} else {
return null
}
}
//删除节点
def delNode(value: Int): Unit = {
if (root == null) { //如果是空树,就不删除
return
}
//先看有没有要删除节点
var targetNode = search(value)
if (targetNode == null) { //没有要删除的节点,就直接返回
return
}
//查找 targetNode 的父节点
var parentNode = searchParent(value)
//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) { // targetNode 只有两个子节点
val value = delRightTreeMin(targetNode.right)
targetNode.value = value
} else { //只有 targetNode 只有一个子节点
//判断 targetNode 是 parentNode 的左子节点还是右子节点
if (targetNode.left != null) { //要删除的节点的左子节点不为空
//判断 targetNode 是 parentNode 的左还是右
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("当前二叉树为空,不能遍历")
}
}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值