二叉排序树

二叉排序树

定义:左子树小于根节点,右子树大于根节点,不一定是平衡树。

散列表的插入查找删除基本已经做到了O(1)但好多时候还用二叉查找树原因:

(1)本身底层结构使然 :散列表底层是数组,且采用散列函数确定位置,散列函数等的设计所要考虑因素多,扩容缩容处理比较复杂,由于散列函数以及哈希冲突的存在,速度不一定优于二叉树。而二叉树采用树的结构,随用随申请空间,且只需要考虑平衡性的问题,较为成熟,且使用红黑树查找删除等操作的固定复杂度为logn

(2)不同场景应用:散列表无序,而二叉树是有序的结构,中序遍历输出一个有序的数据。
具体实现:


public class TreeNode {
	public int val;
	public TreeNode left;
	public TreeNode right;
	TreeNode(int val){
		this.val=val;
	}
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

//二叉查找树
public class BinarySearchTree {
	private static TreeNode tree;
	public static void main(String[] args) {
		BinarySearchTree a=new BinarySearchTree();
		a.init();
		a.delete(1);
		System.out.println(a.find(4));
		System.out.println(a.searchMin().val);
		System.out.println(a.searchMax().val);
		
		a.preOrderTraversalRecursive(tree);
		System.out.println();
		a.preOrderTraversal();
		
		a.midOrderTraversalRecursive(tree);
		System.out.println();
		
		a.backOrderTraversalRecursive(tree);
		System.out.println();
		
		System.out.println(a.sequenceNumberRecursive(tree));
	}
	public void init() {
		int[] m= {2,5,4,3,6,9,1};
		for(int i=0;i<m.length;i++) {
			insert(m[i]);
		}
	}
    public boolean find(int data){
    	TreeNode p=tree;//保证改变后原本的指针没变,还在根节点,便于后续操作
    	while(p!=null) {
    		if(p.val<data) {
    			p=p.right;
    		}
    		else if(p.val>data) {
    			p=p.right;
    		}
    		else {
    			return true;
    		}
    	}
    	return false;
    }
    public void insert(int data){
    	TreeNode p=tree;
    	if(tree==null) {
    		tree=new TreeNode(data);
    		return ;
    	}
    	while(p!=null) {
    		if(data>p.val) {
    			if(p.right==null)
    				{
    					p.right=new TreeNode(data);
    					return;
    				}
    			else
    				p=p.right;
    		}
    		else {//data<p.val
    			if(p.left==null) {
    				p.left=new TreeNode(data);
    				return;
    			}
    			else
    				p=p.left;
    		}	
    	}
    }
    public void delete(int data) {
    	//删除分为三种情况,(1)待删除结点无子节点,只需删除本身以及指向他的引用(2)有一个子节点,只需把子节点放到删除结点的位置
    	//(3)两个子节点,需要找到该点右子树的最左结点,因为最左结点是根节点右边最小的一个,同时也比根节点左边的都大
    	TreeNode p=tree;
    	TreeNode pp=null;//指向要删除结点的父节点
    	while(p!=null&&p.val!=data) {//寻找待删除结点p
    		pp=p;
    		if(data>p.val) {
    			p=p.right;
    		}
    		else {
    			p=p.left;
    		}
    	}
    	if(p==null) {
    		return;//不存在这个点
    	}
    	
    	if(p.left!=null&&p.right!=null) {//左右子树都有
    		TreeNode minpp=p;
    		TreeNode minp=p.right; 
    		while(minp!=null) {//最左结点get
    			minpp=minp;
    			minp=minp.left;
    		}
    		p.val=minp.val;//p的数据赋值为minp的
    		//删除结点minp???
    		//p=minp;
    		//pp=minpp;//这个是放到后面一起处理了,也可以直接赋值为null。
    		minpp.left=null;
    	}
    	 
    	//仅有一个子树或者是叶节点
    	TreeNode child=null;
    	if(p.left!=null)
    		child=p.left;
    	else if(p.right!=null)
    		child=p.right;
    	else;
    	
    	if(pp==null) {//删除的是根节点
    		tree=child;
    	}
    	else if(p==pp.left)//左子树
    		pp.left=child;
   		else //左子树
   			pp.right=child;  
    }
    //求二叉树的最小结点
    public TreeNode searchMin() {
    	if(tree==null)
    		return tree;
    	TreeNode p=tree;
    	while(p.left!=null) {
    		p=p.left;
    	}
    	return p;
    }
    //求二叉树的最大结点
    public TreeNode searchMax() {
    	if(tree==null)
    		return tree;
    	TreeNode p=tree;
    	while(p.right!=null) {
    		p=p.right;
    	}
    	return p;
    }
    //递归实现先中后序遍历
    public void preOrderTraversalRecursive(TreeNode p) {
    	if(p==null)
    		return;
    	System.out.print(p.val+" ");
    	preOrderTraversalRecursive(p.left);
   		preOrderTraversalRecursive(p.right);
    }
    public void midOrderTraversalRecursive(TreeNode p) {
    	if(p==null)
    		return;
    	midOrderTraversalRecursive(p.left);
    	System.out.print(p.val+" ");
   		midOrderTraversalRecursive(p.right);
    }
    public void backOrderTraversalRecursive(TreeNode p) {
    	if(p==null)
    		return;
    	backOrderTraversalRecursive(p.left);
    	backOrderTraversalRecursive(p.right);
   		System.out.print(p.val+" ");
    }
    //求二叉树层数
    public int sequenceNumberRecursive(TreeNode p) {
    	int a=0;
    	if(p==null)
    	    return 0;
    	a=Math.max(sequenceNumberRecursive(p.left),sequenceNumberRecursive(p.right))+1;
    	return a;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值