impl delete for BST

This commit is contained in:
Ivan Li 2019-01-08 13:57:39 +08:00
parent c7bea977cf
commit 0f9dd9012d
2 changed files with 84 additions and 0 deletions

View File

@ -56,4 +56,76 @@ class BinarySearchTree(var root: Option[Node[Int]]) extends BinaryTree[Int] {
} }
p p
} }
def delete(data: Int): Unit = {
//there are 3 scenarios
//1: data is leaf node
//2: data has one child node
//3: data has two child nodes, we need to find out the smallest node from right branch
var p = root
var pp: Option[Node[Int]] = None //parent node of deleted node
//find matching node to delete
breakable {
while (p.isDefined) {
if (data > p.get.data) {
pp = p
p = p.get.right
} else if (data < p.get.data) {
pp = p
p = p.get.left
} else {
//find the value
break
}
}
}
if (p.isEmpty) {
//find nothing
return
}
//now we find the node to delete
//scenario 3
if (p.get.left.isDefined && p.get.right.isDefined) {
//need to find out the smallest node in right branch
var minPP = p
var minP = p.get.right
while (minP.get.left.isDefined) {
minPP = minP
minP = minP.get.left
}
//assign the smallest value in the right branch to the node to be deleted
p.get.data = minP.get.data
//now problems becomes delete the minP in the tree
//minP must not have any left child node
//minP may or may not have right child node
//it will fall back to scenario 1 or 2
p = minP
pp = minPP
}
//child is the child of p
var child: Option[Node[Int]] = None
if (p.get.left.isDefined) {
child = p.get.left
} else if (p.get.right.isDefined) {
child = p.get.right
}
//starting the node deletion
pp match {
case None => root = child
case Some(parentNode) => {
if (parentNode.left.isDefined && (parentNode.left.get.data == p.get.data)) {
parentNode.left = child
} else if (parentNode.right.isDefined && (parentNode.right.get.data == p.get.data)) {
parentNode.right = child
}
}
}
}
} }

View File

@ -40,4 +40,16 @@ class BinarySearchTreeTest extends FlatSpec with Matchers {
assert(tree.find(100).isEmpty) assert(tree.find(100).isEmpty)
} }
it should "delete" in {
val tree = new BinarySearchTree(None)
val nums = Array(33, 17, 50, 13, 18, 34, 58, 16, 25, 51, 66, 19, 27, 55)
nums.foreach(tree.insert)
tree.delete(13)
tree.inOrder(tree.root) should equal(nums.sorted.tail.mkString(""))
tree.delete(18)
tree.inOrder(tree.root) should equal("1617" + nums.sorted.slice(4, nums.size).mkString(""))
tree.delete(66)
tree.inOrder(tree.root) should equal("1617" + nums.sorted.slice(4, nums.size-1).mkString(""))
}
} }