package com.coding.basic;
import java.util.Queue;
import java.util.Stack;
import java.util.LinkedList;
/**
二叉树
5
/ \
2 7
/ \ /\
1 4 6 8
1.前序遍历: 5 2 1 4 7 6 8
2.中序遍历: 1 2 4 5 6 7 8
3.后序遍历: 1 4 2 6 8 7 5
*/
public class BinarySearchTree<T extends Comparable<? super T>> {
private BinarySearchTreeNode<T> root; //root node
public BinarySearchTreeNode<T> getRoot() {
return root;
}
public void setRoot(BinarySearchTreeNode<T> root) {
this.root = root;
}
/**
* 二叉树插入节点
* @param data 节点元素
* @return 插入的节点
*/
public BinarySearchTreeNode<T> insert(T data){
if(root == null){
root = new BinarySearchTreeNode<T>(data);
return root;
}
//root非空
BinarySearchTreeNode<T> current = root;
while(true){
//当前节点的数据小于data
if(current.getData().compareTo(data) >= 0){
if(current.getLeft() != null){
current = current.getLeft();
}else {
BinarySearchTreeNode<T> child = new BinarySearchTreeNode<T>(data);
current.setLeft(child);
child.setParent(current);
return child;
}
}else {//当前节点数据大于root
if(current.getRight() != null){
current = current.getRight();
}else {
BinarySearchTreeNode<T> child = new BinarySearchTreeNode<T>(data);
current.setRight(child );
child.setParent(current);
return child;
}
}
}
}
/**
* 查找元素data
* @param data 要查找的元素
* @return 返回true找到、false未找到
*/
public boolean contains(T data){
if(root == null){
return false;
}
BinarySearchTreeNode<T> current = root;
while(true){
if(current.getData().compareTo(data) > 0){
if(current.getLeft() != null){
current = current.getLeft();
}else{
return false;
}
}else if(current.getData().compareTo(data) < 0){
if(current.getRight() != null){
current = current.getRight();
}else {
return false;
}
}else {
return true;
}
}
}
/**
* 前序遍历递归实现 根节点 左子树 右子树
* @param n 根节点
*/
public void preOrder(BinarySearchTreeNode<T> n){
System.out.print(n.getData()+" ");
if(n.getLeft() != null){
preOrder(n.getLeft());
}
if(n.getRight() != null){
preOrder(n.getRight());
}
}
/**
* 中序遍历递归实现 左子树 根节点 右子树
* @param n 根节点
*/
public void midOrder(BinarySearchTreeNode<T> n){
if(n.getLeft() != null){
midOrder(n.getLeft());
}
System.out.print(n.getData()+" ");
if(n.getRight() != null){
midOrder(n.getRight());
}
}
/**
* 后序遍历递归实现 左子树 右子树 根节点
* @param n 根节点
*/
public void postOrder(BinarySearchTreeNode<T> n){
if(n.getLeft() != null){
postOrder(n.getLeft());
}
if(n.getRight() != null){
postOrder(n.getRight());
}
System.out.print(n.getData()+" ");
}
/**
* 非递归实现前序遍历
*/
public void preOrderWithoutRecursion(){
if(root == null){ //根节点为空
return;
}
Stack<BinarySearchTreeNode<T>> stack = new Stack<>(); //存放未执行完的节点
stack.push(root); //首先push根节点
BinarySearchTreeNode<T> current = null;
while(!stack.isEmpty()){ //栈内还有节点
current = stack.peek(); //得到栈顶节点
if(current.getState() == 0){
System.out.print(current.getData() + " "); //打印数据
current.setState(1);
}else if(current.getState() == 1){
if(current.getLeft() != null){
stack.push(current.getLeft());
}
current.setState(2); //确认是否有左子树
}else if(current.getState() == 2){
if(current.getRight() != null){
stack.push(current.getRight());
}
current.setState(3); //确认是否有右子树
}else if(current.getState() == 3){
stack.pop(); //删除栈顶节点(该节点已经执行完所有程序)
current.setState(0);
}
}
}
/**
* 非递归实现中序遍历
*/
public void midOrderWithoutRecursion(){
if(root == null){ //根节点为空
return;
}
Stack<BinarySearchTreeNode<T>> stack = new Stack<>(); //存放未执行完的节点
stack.push(root); //首先push根节点
BinarySearchTreeNode<T> current = null;
while(!stack.isEmpty()){ //栈内还有节点
current = stack.peek(); //得到栈顶节点
if(current.getState() == 0){
if(current.getLeft() != null){
stack.push(current.getLeft()); //确认是否有左子树
}
current.setState(1);
}else if(current.getState() == 1){
System.out.print(current.getData() + " "); //打印数据
current.setState(2);
}else if(current.getState() == 2){
if(current.getRight() != null){
stack.push(current.getRight());
}
current.setState(3); //确认是否有右子树
}else if(current.getState() == 3){
stack.pop(); //删除栈顶节点
current.setState(0);
}
}
}
/**
* 非递归实现后序遍历
*/
public void postOrderWithoutRecursion(){
if(root == null){ //根节点为空
return;
}
Stack<BinarySearchTreeNode<T>> stack = new Stack<>(); //存放未执行完的节点
stack.push(root); //首先push根节点
BinarySearchTreeNode<T> current = null;
while(!stack.isEmpty()){ //栈内还有节点
current = stack.peek(); //得到栈顶节点
if(current.getState() == 0){
if(current.getLeft() != null){
stack.push(current.getLeft());
}
current.setState(1);
}else if(current.getState() == 1){
if(current.getRight() != null){
stack.push(current.getRight());
}
current.setState(2); //确认是否有左子树
}else if(current.getState() == 2){
System.out.print(current.getData() + " "); //打印数据
current.setState(3); //确认是否有右子树
}else if(current.getState() == 3){
stack.pop(); //删除栈顶节点
current.setState(0);
}
}
}
/**
* 层次遍历
1.先根结点入队列
2.从队列中取出一个元素
3.访问该元素的节点
4.若该元素所指节点的左右子节点非空,则将左右孩子节点分别按照指针顺序入栈
*/
public void traveralByLevel(BinarySearchTreeNode<T> n){
if(n == null) return;
Queue<BinarySearchTreeNode<T>> queue = new LinkedList<BinarySearchTreeNode<T>>();
queue.offer(n); //入队列
while(!queue.isEmpty()){
BinarySearchTreeNode<T> node = queue.poll(); //出队列
System.out.print(node.getData() + " ");
if(node.getLeft() != null) queue.offer(node.getLeft());
if(node.getRight() != null) queue.offer(node.getRight());
}
}
//删除某个节点n
public void delete(BinarySearchTreeNode<T> n){
BinarySearchTreeNode<T> p = n.getParent(); //节点的父节点
BinarySearchTreeNode<T> child; //节点的子节点
//该节点没有任何子节点。// 叶子结点,直接删除即可。要考虑待删除结点是root的情况。
if(n.getLeft()==null && n.getRight()==null){
//该节点是根节点
if(n == root){
root = null;
return ;
}
//非根节点
if(n == p.getLeft()){
p.setLeft(null);
}else if(n == p.getRight()){
p.setRight(null);
}
}
// 内部结点,把它的后继的值拷进来,然后递归删除它的后继。
else if(n.getLeft()!=null && n.getRight()!=null){
BinarySearchTreeNode<T> next = successor(n); //找到n的中序后继节点
n.setData(next.getData());
delete(next); //中序后继节点
}
//只有一个孩子的结点,把它的孩子交给它的父结点即可
else {
if(n.getLeft() != null){ //得到子节点
child = n.getLeft();
}else {
child = n.getRight();
}
if(n == root){ // n是根节点的情况
child.setParent(null);
root = child;
return;
}
//非根节点
if(n == p.getLeft()){
p.setLeft(child);
child.setParent(p);
}else{
p.setRight(child);
child.setParent(p);
}
}
}
//找到n的中序后继节点
public BinarySearchTreeNode<T> successor(BinarySearchTreeNode<T> n){
if( n == null) return null;
if( n.getRight() == null ) return null;
return findMin(n.getRight());
}
//查找n树的最小值
public BinarySearchTreeNode<T> findMin(BinarySearchTreeNode<T> n){
BinarySearchTreeNode<T> current = n;
while(current.getLeft() != null){
current = current.getLeft();
}
return current;
}
//查找n树的最大值
public BinarySearchTreeNode<T> findMax(BinarySearchTreeNode<T> n){
BinarySearchTreeNode<T> current = n;
while(current.getRight() != null){
current = current.getRight();
}
return current;
}
/*
求树的高度(利用后序遍历)
*/
public int postOrderGetHeight(BinarySearchTreeNode<T> n){
int hL = 0, hR = 0, maxH = 0;
if(n != null){
hL = postOrderGetHeight(n.getLeft()); //求左子树深度
hR = postOrderGetHeight(n.getRight()); //求右子树深度
maxH = hL> hR? hL : hR ; //求左右子树深度最大的那个
return (maxH+1);//返回树的深度
}
return 0; //空树返回0
}
}