# Java实现二叉树基本操作

package cn.com.cnn;

import java.util.ArrayDeque;
import java.util.Stack;

public class MyTree {

public class Node {
int value;
Node leftChild;
Node rightChild;

public Node(int value) {
this.value = value;
leftChild = null;
rightChild = null;
}

public void display() {
System.out.print(value + " ");
}
}

public static void main(String[] args) {
int[] data = {2, 4, 1, 9, 70, 6, 10};
MyTree myTree = new MyTree();
Node root = null;
for(int i = 0; i < data.length; i++) {
root = myTree.insertNodeRec(root, data[i]);
}
System.out.print("中序遍历 ");
myTree.inOrderTranverse(root);
myTree.inOrderTranverseStack(root);
System.out.print("先序遍历 ");
myTree.preOrderTranverse(root);
myTree.preOrderTranverseStack(root);
System.out.print("后序遍历 ");
myTree.afterOrderTranverse(root);
myTree.afterOrderTranverseStack(root);
System.out.print("广度优先遍历 ");
myTree.widthTranverse(root);
Node findNode = myTree.findKey(root, 10);
System.out.println("查找到的值是" + findNode.value);
Boolean ifDelete = myTree.delete(root, 4);
System.out.println(ifDelete);

}

public Node createBinaryTree(int[] data) {
Node root = null;
if(data == null) {
return root;
}

MyTree myTree = new MyTree();
for(int i : data) {
root = myTree.insertNodeRec(root, i);
}

return root;
}

public void inOrderTranverse(Node root) {
if(root == null) {
return;
}
inOrderTranverse(root.leftChild);
root.display();
inOrderTranverse(root.rightChild);
}

public void inOrderTranverseStack(Node root) {
Stack<Node> nodes = new Stack<Node>();
Node current = root;
while(current != null || !nodes.isEmpty()) {
while(current != null) {
nodes.push(current);
current = current.leftChild;
}
if(!nodes.isEmpty()) {
current = nodes.pop();
current.display();
current = current.rightChild;
}
}
}

public void preOrderTranverse(Node root) {
if(root == null) {
return;
}
root.display();
preOrderTranverse(root.leftChild);
preOrderTranverse(root.rightChild);
}

public void preOrderTranverseStack(Node root) {
Stack<Node> nodes = new Stack<Node>();
Node current = root;
while(current != null || !nodes.isEmpty()) {
while(current != null) {
current.display();
nodes.push(current);
current = current.leftChild;
}
if(!nodes.isEmpty()) {
current= nodes.pop();
current = current.rightChild;
}
}
}

public void afterOrderTranverse(Node root) {
if(root == null) {
return;
}
afterOrderTranverse(root.leftChild);
afterOrderTranverse(root.rightChild);
root.display();
}

public void afterOrderTranverseStack(Node root) {
Stack<Node> nodes = new Stack<Node>();
Node current = root;
Node preNode = null;
while(current != null || !nodes.isEmpty()) {
while(current != null) {
nodes.push(current);
current = current.leftChild;
}
if(!nodes.isEmpty()) {
current = nodes.peek().rightChild;
if(current == null || current == preNode) {
current = nodes.pop();
current.display();
preNode =current;
current = null;
}
}
}
}

//使用队列实现广度优先遍历
public void widthTranverse(Node root) {
ArrayDeque<Node> nodes = new ArrayDeque<Node>();
Node current = root;
while(!nodes.isEmpty()) {
current =  nodes.remove();
current.display();
if(current.leftChild != null) {
}
if(current.rightChild != null) {
}

}
}

//二分查找
public Node findKey(Node root, int value) {
Node result = root;
while(true) {
if(result == null) {
return result;
}
if(result.value == value) {
return result;
} else if(result.value < value) {
result = result.rightChild;
} else {
result =  result.leftChild;
}
}
}

public Node insertNodeRec(Node root, int value) {
Node current =new Node(value);
if(root == null) {
root = current;

return root;
}
if(root.value < value) {
if(root.rightChild == null) {
root.rightChild = current;
} else {
root.rightChild = insertNodeRec(root.rightChild, value);
}
} else {
if(root.leftChild == null) {
root.leftChild = current;
} else {
root.leftChild = insertNodeRec(root.leftChild, value);
}
}

return root;
}

public Node insertNoRec(Node root, int value) {
Node current = new Node(value);
if(root == null) {
root = current;

return root;
}
Node tmp = root;
while(tmp != null) {
if(tmp.value < value) {
if(tmp.rightChild == null) {
tmp.rightChild = current;
break;
} else {
tmp = tmp.rightChild;
continue;
}
} else {
if(tmp.leftChild == null) {
tmp.rightChild = current;
break;
} else {
tmp = tmp.rightChild;
continue;
}
}

}

return root;

}

public int getMinValue(Node root) {
Node current = root;
while(current.leftChild != null) {
current = current.leftChild;
}
return current.value;
}

public boolean delete(Node root, int value) {
if(root == null) {
return false;
}
Node parent = null;
Node current = root;
Boolean isLeft =true;
while(current.value != value) {
parent = current;
if(current.value < value) {
current = current.rightChild;
isLeft = false;
} else {
current = current.leftChild;
isLeft = true;
}
}
//没找到该节点
if(current == null) {
return false;
}
if(current.leftChild == null && current.rightChild == null) {
if(current == root) {
root = null;
} else {
if(isLeft) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
}
} else if(current.leftChild == null) {
if(current == root) {
root = current.rightChild;
} else if(isLeft) {
parent.leftChild = current.rightChild;
} else {
parent.rightChild = current.rightChild;
}

} else if(current.rightChild == null) {
if(current == root) {
root = current.leftChild;
} else if(isLeft) {
parent.leftChild = current.leftChild;
} else {
parent.rightChild = current.leftChild;
}
} else {
//左右子树都不为空，取右子树中值最小的和current值置换，再删除该最小节点。显然最小节点在右子树最左边。
int minNum = getMinValue(current.rightChild);
current.value = minNum;
//删除current的右子树的最左边点
Node deleteNodes = current.rightChild;
while(deleteNodes.leftChild != null) {
deleteNodes = deleteNodes.leftChild;
}
deleteNodes.leftChild = null;
}

//afterOrderTranverse(root);
return true;
}

}