package 二分搜索树;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class BinarySearchTree1<E extends Comparable<E>> { //comparable代表不能重复
private class Node{ //内部类
public E e;//树节点数据域
public Node left,right;//左子树 右子树
public Node(E e){ //节点的构造函数
this.e=e;
left=null;
right=null;
}
}
private Node root;//根节点
private int size;//节点个数
public BinarySearchTree1(){ //二叉搜索树的构造函数
root=null;
size=0;
}
//获取树中元素的个数
public int size(){
return size;
}
//判断是否为空
public boolean isEmpty(){
return size==0;
}
//将元素e插入二叉树
public void add(E e){
// //迭代实现
// if(size()==0){
// root=new Node(e);
// size++;
// }
// Node p=root;//创建p节点从root开始,向后遍历
// while(p!=null){
// if(e.compareTo(p.e)==0){
// return;
// }else if(e.compareTo(p.e)>0){
// if(p.right!=null){
// p=p.right;
// }else{
// p.right=new Node(e);
// size++;
// return;
// }
//
// }else{
// if(p.left!=null){
// p=p.left;
// }else{
// p.left=new Node(e);
// size++;
// return;
// }
// }
// }
root=add(root,e);//递归
}
//以node为当前树的根节点,添加元素e并返回该树的根
private Node add(Node node,E e){
if(node==null){ //如果node为空的话。新创建一个Node把e传进去当做根节点
size++;
return new Node(e);
}
//新来的e大于当前节点的值,往右走,以node.right为根节点添加e
if(e.compareTo(node.e)>0){
node.right=add(node.right,e);//递归调用
//新来的e小于当前节点的值,往左走,以node.left为根节点添加e
}else if(e.compareTo(node.e)<0){
node.left=add(node.left,e);
}
return node;
}
public boolean contains(E e){
// if(size()==0){ //迭代
// return false;
// }
// Node p=root;
// while(p!=null){
// if(e.compareTo(p.e)>0){
// p=p.left;
// }else if(e.compareTo(p.e)<0){
// p=p.right;
// }else{
// return true;
// }
// }
// return false;
return contains(root,e); //递归
}
//查找以node为节点的树是否包含元素e
public boolean contains(Node node,E e){
if(node==null){
return false;
}
if(e.compareTo(node.e)>0){
//如果要查询的值大于当前节点,就查询右边
return contains(node.right,e);
}else if(e.compareTo(node.e)<0){
return contains(node.left,e);
}else{
return true;
}
}
public void inOrder(){ //中序遍历
ArrayList<E> list=new ArrayList<E>(); //将遍历的节点值存在list集合中
inOrder(root,list);
System.out.println(list);
}
private void inOrder(BinarySearchTree1<E>.Node node, ArrayList<E> list) {
if(node==null){
return;
}
inOrder(node.left,list);
list.add(node.e);
inOrder(node.right,list);
}
public void levelOrder(){//广度优先遍历 --层序遍历
//辅助队列遍历,从根节点开始进队,出队时将其左右孩子进队,依次重复操作,直到所有出队的元素没有孩子节点
ArrayList<E> list=new ArrayList<E>();
Queue<Node> queue=new LinkedList<Node>();
queue.add(root);
while(!queue.isEmpty()){
Node cur=queue.poll();
list.add(cur.e);//把值存进list集合中
if(cur.left!=null){//左孩子不为null
queue.add(cur.left);//则进队
}
if(cur.right!=null){
queue.add(cur.right);
}
}
System.out.println(list);
}
public String toString() {
StringBuilder sb=new StringBuilder();
generateBSTString(root,0,sb);
return sb.toString();
}
private void generateBSTString(Node node, int level,
StringBuilder sb) {
if(node==null){
sb.append(generateDepthString(level)+"null\n");
return ;
}
generateBSTString(node.left,level+1,sb);
sb.append(generateDepthString(level)+node.e+"\n");
generateBSTString(node.right,level+1,sb);
}
private String generateDepthString(int level) { //显示深度
StringBuilder sb=new StringBuilder();
for(int i=0;i<level;i++){
sb.append("-");
}
return sb.toString();
}
//获取最小值
public E minmum(){
if(size()==0){
throw new IllegalArgumentException("tree is empty!");
}
return minmum(root).e;
}
private Node minmum(Node node){
if(node.left==null){ //如果当前节点没有左孩子,则代表当前就是最小值
return node;
}
return minmum(node.left);//否则继续向左走;
}
//获取最大值并返回
public E maxmum(){
if(size()==0){
throw new IllegalArgumentException("tree is empty!");
}
return maxmum(root).e;
}
private Node maxmum(Node node){
if(node.right==null){ //如果当前节点没有右孩子,则代表当前就是最大值
return node;
}
return maxmum(node.right);//否则继续向左走;
}
// 删除最小值
public E removeMin(){
E e=minmum();
root=removeMin(root);
return e;
}
// 以node为根节点的二分搜索树,在删除最小值之后并返回新树的根
private Node removeMin(Node node) {
if(node.left==null){ //left==null,找到最小值以后
Node rightNode=node.right; //把他的右孩子给
node.right=null;
size--;
return rightNode;
}
node.left=removeMin(node.left);//若不是null,继续递归重复上一步
return node;
}
// 删除最大值
public E removeMax(){
E e=maxmum();
root=removeMax(root);
return e;
}
// 以node为根节点的二分搜索树,在删除最大值之后并返回新树的根
private Node removeMax(Node node){
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size--;
return leftNode;
}
node.right=removeMax(node.right);
return node;
}
//删除指定元素
public void remove(E e){
root=remove(root,e);
}
// 以node为根 删除指定元素e之后 返回新树的根
private Node remove(Node node,E e){
if(node==null){
return null;
}
if(e.compareTo(node.e)>0){
node.right=remove(node.right,e);
return node;
}else if(e.compareTo(node.e)<0){
node.left=remove(node.left,e);
return node;
}else{
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size--;
return rightNode;
}
if(node.right==null){
Node leftNode=node.left;
node.left=null;
size--;
return leftNode;
}
Node successor=minmum(node.right);
successor.right=removeMin(node.right);
successor.left=node.left;
node.left=node.right=null;
return successor;
}
}
}