这篇文章和我之前的文章Java学习日记——链表实现全攻略在设计思路上有非常多的相似之处,但是在处理问题上却精进了很多,比如学会了使用?:表达式在选择返回值得时候精简代码,更加频繁地利用递归操作去实现复杂的业务。故将此代码放在本文共各位看官批评
import java.io.Serializable;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedDeque;
import sun.misc.Queue;
/**
* Java实现二叉树
* 要求实现的方法:
* 泛型要求实现Comparable接口,可以比较两个对象的大小
* 判断二叉树是否为空;
* 得到二叉树的节点数量
* 得到二叉树的深度
* 得到二叉树的先序遍历字符串
* 得到二叉树的中序遍历字符串
* 得到二叉树的后序遍历字符串
* 实现删除方法
* 返回最大值节点
* 返回最小值节点
* 返回要查询的节点
* 查询指定节点是否存在
* 清空二叉树
*
* 二叉树的节点要求实现:
* 每一个节点具有三个属性,分别保存节点的data,left,right.要求有单参构造,三参构造。要求判断是否是叶子节点的方法。
*
* 二叉树实现类中要求:
* protect型的root属性保存二叉树根节点
* 重写无参构造方法,初始化root为空
*/
public interface Tree<T extends Comparable> {
public boolean isEmpty() ;
public int size() ;
public int height() ;
public String preOrder() ;
public String inOrder() ;
public String postOrder() ;
public String levelOrder() ;
public void insert(T data) ;
public void remove(T data) ;
public T findMax() ;
public T findMin() ;
public cn.chuchu.main.BinaryNode<T> findNode(T data) ;
public boolean contains(T data) throws Exception ;
public void clear() ;
}
public class BinaryNode<T extends Comparable> implements Serializable {
private static final long serialVersionUID = -6477238039299912313L;
public BinaryNode<T> left;
public BinaryNode<T> right;
public T data;
public BinaryNode(BinaryNode<T> left, BinaryNode<T> right, T data) {
this.left = left;
this.right = right;
this.data = data;
}
public BinaryNode(T data){
this(null,null,data) ;
}
public boolean isLeaf(){
return this.left == null && this.right == null ;
}
}
public class BinarySearchTree<T extends Comparable> implements Tree<T> {
protected BinaryNode<T> root ;
public BinarySearchTree() {
root = null ;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public int size() {
return size(root) ;
}
private int size(BinaryNode<T> subtree) {
if(subtree == null) return 0 ;
else
return size(subtree.left) + size(subtree.right) + 1 ;
}
@Override
public int height() {
return height(root);
}
private int height(BinaryNode<T> subtree) {
if(subtree == null) return 0 ;
else{
int left = height(subtree.left) ;
int right = height(subtree.right) ;
return (left > right) ? (left + 1) : (right + 1) ;
}
}
@Override
public String preOrder() {
String result = preOrder(root) ;
return result;
}
private String preOrder(BinaryNode<T> subtree) {
StringBuffer sb = new StringBuffer() ;
if(subtree != null){
sb.append(subtree.data) ;
sb.append(preOrder(subtree.left)) ;
sb.append(preOrder(subtree.right)) ;
}
return sb.toString();
}
@Override
public String inOrder() {
String result = inOrder(root) ;
return result ;
}
private String inOrder(BinaryNode<T> subtree) {
StringBuffer sb = new StringBuffer() ;
if(subtree != null){
sb.append(inOrder(subtree.left)) ;
sb.append(subtree.data) ;
sb.append(inOrder(subtree.right)) ;
}
return sb.toString();
}
@Override
public String postOrder() {
String result = postOrder(root) ;
return result;
}
private String postOrder(BinaryNode<T> subtree) {
StringBuffer sb = new StringBuffer() ;
if(subtree != null){
sb.append(postOrder(subtree.left)) ;
sb.append(postOrder(subtree.right)) ;
sb.append(subtree.data) ;
}
return sb.toString();
}
@Override
public String levelOrder() {
LinkedList<BinaryNode<T>> queue = new LinkedList<>() ;
StringBuffer sb = new StringBuffer() ;
BinaryNode<T> p = this.root ;
while(p != null){
sb.append(p.data) ;
if(p.left != null)
queue.add(p.left) ;
if(p.right != null)
queue.add(p.right) ;
p = queue.poll() ;
}
return sb.toString() ;
}
@Override
public void insert(T data) {
if(data == null)
throw new RuntimeException("传入的数据不能为空") ;
this.root = insert(data , root) ;
}
private BinaryNode<T> insert(T data, BinaryNode<T> p) {
if(p == null)
p = new BinaryNode<>(null, null, data) ;
int compareResult = data.compareTo(p.data) ;
if(compareResult < 0)
p.left = insert(data , p.left) ;
if(compareResult > 0)
p.right = insert(data , p.right) ;
else{;}//已有元素不做处理
return p;
}
@Override
public void remove(T data) {
if(data == null)
throw new RuntimeException("传入的数据不能为空") ;
root = remove(data , root) ;
}
private BinaryNode<T> remove(T data, BinaryNode<T> p) {
if(p == null)
return p ;
int compareResult = data.compareTo(p.data) ;
if(compareResult < 0)
p.left = remove(data, p.left) ;
else if(compareResult > 0)
p.right = remove(data, p.right) ;
else if(p.left != null && p.right != null){
p.data = findMin(p.right).data ;
p.right = remove(p.data , p.right) ;
}else{
p = (p != null ) ? p.left : p.right ;
}
return p;
}
@Override
public T findMin() {
if(isEmpty())
throw new NullPointerException("当前二叉树为空") ;
return findMin(root).data ;
}
private BinaryNode<T> findMin(BinaryNode<T> p) {
if(p == null) return null ;
else if (p.left == null)
return p ;//如果没有左子树,p就是最小的节点
return findMin(p.left) ;
}
@Override
public T findMax() {
if(isEmpty())
throw new NullPointerException("当前二叉树为空") ;
return findMax(root).data ;
}
private BinaryNode<T> findMax(BinaryNode<T> p) {
if(p == null) return null ;
else if(p.right == null)
return p ;
return findMax(p.right) ;
}
@Override
public BinaryNode<T> findNode(T data) {
return findNode(data , root);
}
private BinaryNode<T> findNode(T data, BinaryNode<T> root) {
if(root == null) return null ;
int compareResult = data.compareTo(root.data) ;
if(compareResult < 0 ){
if(root.left != null)
return findNode(data , root.left) ;
else
return null ;
}else if(compareResult > 0){
if(root.right != null)
return findNode(data , root.right) ;
else
return null ;
}else
return root ;
}
@Override
public boolean contains(T data) throws Exception {
return contains(data , root) ;
}
private boolean contains(T data, BinaryNode<T> root) {
if(root == null) return false ;
int compareResult = data.compareTo(root.data) ;
if(compareResult < 0){
if(root.left != null)
return contains(data , root.left) ;
else
return false ;
}else if(compareResult > 0){
if(root.right != null)
return contains(data , root.right) ;
else
return false ;
}else
return true ;
}
@Override
public void clear() {
root = null ;
}
}