二分搜索树

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);
		
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值