package p04.二分搜索树;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
树:元素与元素之间存在一对多的关系 层次关系
二叉树:就是一种特殊的树结构 元素节点最多有两个孩子节点
二叉树怎么存? 动态数组 动态链表
深度为h的二叉树 最大有2^h-1个节点
第n层最大有 2^(n-1)个节点
如果二叉树不是一个平衡二叉树,那么用动态数组存有很多空间浪费
平衡:
满二叉树:叶子节点的深度差为0 且最后一层全是叶子节点
完全二叉树:是按照每一层从左到右填充节点 叶子节点的深度差<=1
满二叉树一定是完全二叉树
完全二叉树不一定是满二叉树
二分搜索树:就是一个二叉树,只不过有限定条件
其左子树中所有的节点都小于该节点
其右子树中所有的节点都大于该节点
不能存储重复元素
平衡的树:二分搜索树 二叉排序树 二叉顺序树
时间复杂度为O(logN) 二分查找 插入排序 二分搜索树
*/
public class BinarySearchTree<E extends Comparable<E>> {
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 BinarySearchTree(){
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;
while(true){
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(e.compareTo(p.e)<0){
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){
size++;
Node n=new Node(e);
return n;
}
if(e.compareTo(node.e)>0){
node.right=add(node.right,e);
}else if(e.compareTo(node.e)<0){
node.left=add(node.left,e);
}
return node;
}
//查找e元素是否在树中
public boolean contains(E e){
//迭代实现
if(size()==0){
return false;
}
Node p=root;
while(p!=null){
if(e.compareTo(p.e)==0){
return true;
}else if(e.compareTo(p.e)>0){
p=p.right;
}else if(e.compareTo(p.e)<0){
p=p.left;
}
}
return false;
//递归实现
// return contains(root,e);
}
private 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>();
inOrder(root,list);
System.out.println(list);
}
private void inOrder(Node node, ArrayList<E> list) {
if(node==null){
return;
}
inOrder(node.left,list);
list.add(node.e);
inOrder(node.right, list);
}
//前序遍历
public void preOrder(){
ArrayList<E> list=new ArrayList<E>();
preOrder(root,list);
System.out.println(list);
}
private void preOrder(Node node, ArrayList<E> list) {
if(node==null){
return;
}
list.add(node.e);
preOrder(node.left, list);
preOrder(node.right, list);
}
//后序遍历
public void postOrder(){
ArrayList<E> list=new ArrayList<E>();
postOrder(root,list);
System.out.println(list);
}
private void postOrder(Node node, ArrayList<E> list) {
if(node==null){
return;
}
postOrder(node.left, list);
postOrder(node.right, list);
list.add(node.e);
}
//层序遍历 广度优先遍历
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);
if(cur.left!=null){
queue.add(cur.left);
}
if(cur.right!=null){
queue.add(cur.right);
}
}
System.out.println(list);
}
@Override
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 minnum(){
if(size()==0){
throw new IllegalArgumentException("树为空");
}
return minnum(root).e;
}
//以node为根节点 查找该树中的最小值
private Node minnum(Node node){
if(node.left==null){
return node;
}
return minnum(node.left);
}
//获取最大值
public E maxnum(){
if(size()==0){
throw new IllegalArgumentException("树为空");
}
return maxnum(root).e;
}
private Node maxnum(Node node) {
if(node.right==null){
return node;
}
return maxnum(node.right);
}
//删除最小值
public E removeMin(){
E e=minnum();
root=removeMin(root);
return e;
}
//以node为根节点的二分搜索树,在删除最小值之后并返回新树的根
private Node removeMin(Node node) {
if(node.left==null){
Node rightNode=node.right;
node.right=null;
size--;
return rightNode;
}
node.left=removeMin(node.left);
return node;
}
//删除最大值
public E removeMax(){
E e=maxnum();
root=removeMax(root);
return e;
}
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=minnum(node.right);
successor.right=removeMin(node.right);
successor.left=node.left;
node.left=node.right=null;
return successor;
}
}
}
测试
package p04.二分搜索树;
public class Main {
public static void main(String[] args) {
BinarySearchTree<Integer> bst=new BinarySearchTree<Integer>();
bst.add(5);
bst.add(9);
bst.add(2);
bst.add(7);
bst.add(3);
bst.add(1);
bst.add(6);
bst.add(8);
System.out.println(bst.size());
bst.inOrder();
bst.preOrder();
bst.postOrder();
bst.levelOrder();
System.out.println(bst);
System.out.println(bst.maxnum());
System.out.println(bst.minnum());
System.out.println(bst.removeMin());
System.out.println(bst.removeMax());
bst.levelOrder();
System.out.println(bst);
System.out.println("==================");
bst.remove(5);
bst.levelOrder();
System.out.println(bst);
}
}