实际上,如果不采用换节点的方式,而采用替换数据的方式,操作会更简单,但是为了清楚的表现出算法思想,这里采用换节点的方式
public class BinaryTree {
class Node{
int value;
Node left;
Node right;
Node(int value){this.value = value;}
}
private Node root;
public Node getRoot() {
return this.root;
}
// add node
private void addNode(Node node,Node newNode) {
if(newNode.value == node.value) return;
else if(newNode.value < node.value)
if(node.left == null) {
node.left = newNode;
return;
}else addNode(node.left,newNode);
else
if(node.right == null) {
node.right = newNode;
return;
}else addNode(node.right,newNode);
}
public void add(int value) {
// process empty binary tree
if(root == null) {
root = new Node(value);
return;
}
Node newNode = new Node(value);
addNode(root,newNode);
}
public boolean remove(int target) {
Node parent = null, current = root;
boolean isLeftNode = true; // record left or right
// find target
while(current != null && current.value != target) {
parent = current;
if(current.value > target) {
if(current.left == null)
current = null;
else {
current = current.left;
isLeftNode = true;
}
}else {
if(current.right == null)
current = null;
else {
current = current.right;
isLeftNode = false;
}
}
}
// case 1: NOT FOUND
if(current == null) return false;
// case 2: there aren't children node
else if(current.left == null && current.right == null) {
if(current == root) root = null;
else if(isLeftNode) parent.left = null;
else parent.right = null;
// case 3 : there is a children node
}else if(current.left == null && current.right != null){
if(current == root) root = current;
else if(isLeftNode) parent.left = current.right;
else parent.right = current.right;
}else if(current.left != null && current.right == null) {
if(current == root) root = current;
else if(isLeftNode) parent.left = current.left;
else parent.right = current.left;
// case 4: there are two children node
}else {
/*
* 1、find the minimum children node of right node
* 2、the minimum node replaces the target node
*/
Node minParent = current;
Node minNode = current.right;
while(minNode != null && minNode.left != null) {
minParent = minNode;
minNode = minNode.left;
}
if(minParent == current) {
minNode.left = current.left;
}else {
minParent.left = null;
minNode.right = current.right;
minNode.left = current.left;
}
if(parent==null) root = minNode;
else if(isLeftNode) parent.left = minNode;
else parent.right = minNode;
}
return true;
}
// first self, then left, then right
public void preOrderTraversal(Node node) {
if(node == null) return;
System.out.printf("%d ",node.value);
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
// first left, then self, then right
public void inOrderTraversal(Node node) {
if(node == null) return;
inOrderTraversal(node.left);
System.out.printf("%d ",node.value);
inOrderTraversal(node.right);
}
// first left, then right, then self
public void postOrderTraversal(Node node) {
if(node == null) return;
postOrderTraversal(node.left);
postOrderTraversal(node.right);
System.out.printf("%d ",node.value);
}
}