数据结构之二叉排序树

数据结构之二叉排序树

二叉排序树:或者是一颗空树;或者是具有下列性质的二叉树:1)若他的左子树不空,则左子树上所有结点的值均小于它的根节点的值;2)若他的右子树不为空,则右子树上所有节点的值均大于它的根节点的值;3)他的左右子树也分别为二叉排序树。

二叉排序树的创建以及增删改查
package treelearning;

import java.util.Scanner;

public class BiSearchTree {    
    private TreeNode root;//定义根节点属性便于操作

    public TreeNode getRoot() {
        return root;
    }
    public void setRoot(TreeNode root) {
        this.root = root;
    }
    //创建一颗二叉排序树,实质上就是一颗空树的依次插入。
    public void creatBST(int[] datas)
    {   
        //按输入顺序依次插入节点
        for(int i=0;i<datas.length;i++)
        {
            this.InsertBST(datas[i]);
        }
    }
    //查找二叉树的节点,给外部的方法
    public void searchBST(int target)
    {   
        if(root==null)
        System.out.println("该树为空树");
        else this.searchBST(root, target,null);
    }
    /*
     * @param:tempNode,指向当前节点;preNode,当前节点的双亲节点;target,目标所需要查找的值。
     * 实际的迭代查找,查找成功返回当前节节点,即目标节点;查找失败则返回查找路径上的最后一个节点,即插入该元素的双亲节点。
     */
    private TreeNode searchBST(TreeNode tempNode,int target,TreeNode preNode)
    { 
        if(tempNode==null) {tempNode=preNode;  return tempNode; }
        else if(target==tempNode.getThreshold()) return tempNode;
        else if(target<tempNode.getThreshold()) return this.searchBST(tempNode.getLeftchild(), target,tempNode);
        else return this.searchBST(tempNode.getRightchild(), target,tempNode);
    }
    /*
     * 因为查找失败反回了该节点插入的双亲节点的位置,只需判断应该插入在双亲节点的哪个节点即可。
     */
    public void InsertBST(int target)
    {
        TreeNode targetNode=this.searchBST(root, target,null);
        if(targetNode==null)
        {   
            //System.out.print(target+" ");
            targetNode=new TreeNode();
            targetNode.setThreshold(target);
            this.setRoot(targetNode);
        }
        else if(target<targetNode.getThreshold()) {
            TreeNode insertNode=new TreeNode();
            insertNode.setThreshold(target);
            targetNode.setLeftchild(insertNode);
        }
        else if(target>targetNode.getThreshold()) {
            TreeNode insertNode=new TreeNode();
            insertNode.setThreshold(target);
            targetNode.setRightchild(insertNode);
        }
        else System.out.println("您要插入的节点已经存在"); 
    }
    public void deleteBST(int target)
    {   
        TreeNode targetNode=this.deleteBST(root, target);
        //System.out.println(targetNode.getThreshold());
        this.searchPreNode(targetNode, this.getRoot(),this.getRoot());
        //System.out.println(preNode.getThreshold());
        if(targetNode==null) System.out.println("您要删除的节点不存在");
        //删除的节点为叶子节点
        else if(targetNode.getLeftchild()==null&&targetNode.getRightchild()==null)
        {
           if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(null);
           else parentNode.setRightchild(null);
        }
        //删除的节点左节点为空,只需把双亲节指向该节点的指针换成该节点的右节点即可。
        else if(targetNode.getLeftchild()==null)
        {   
            if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(targetNode.getRightchild());
            else parentNode.setRightchild(targetNode.getRightchild());
        }
        //删除的节点右节点为空,只需把双亲节指向该节点的指针换成该节点的左节点即可。
        else if(targetNode.getRightchild()==null)
        {
            if(parentNode.getLeftchild().equals(targetNode)) parentNode.setLeftchild(targetNode.getLeftchild());
            else parentNode.setRightchild(targetNode.getLeftchild());
        }
        //删除节点的左右节点都不为空,找到删除节点的直接前驱节点;直接前驱节点的双亲节点右节点指向该前驱结点的左子树。把删除节点替换称直接前驱节点即可。
        else {
          TreeNode preNode=targetNode;TreeNode tempNode=targetNode.getLeftchild();
          while(tempNode.getRightchild()!=null) {preNode=tempNode; tempNode=tempNode.getRightchild();}
          //System.out.println("前继节点为"+tempNode.getThreshold()+",前继节点的双亲为"+preNode.getThreshold()+",删除节点的双亲为"+parentNode.getThreshold());
          targetNode.setThreshold(tempNode.getThreshold());
          if(!preNode.equals(targetNode)) preNode.setRightchild(tempNode.getLeftchild());
          else preNode.setLeftchild(tempNode.getLeftchild());
          tempNode.setLeftchild(null);//等待jvm自动回收
        }
        parentNode=null;//全局变量用完后初始化。
    }
    private static TreeNode parentNode=null;//记录要删除节点的双亲节点
    /*
     * 找到删除节点的双亲节点
     */
    public void searchPreNode(TreeNode target,TreeNode tempNode,TreeNode preNode)
    {   
        if(tempNode!=null)
        {   
            if(tempNode.equals(target)) parentNode=preNode; 
            else {
                this.searchPreNode(target, tempNode.getLeftchild(), tempNode);
                this.searchPreNode(target, tempNode.getRightchild(), tempNode); 
            }            
        }
    }
    /*
     * 找到删除节点并返回该节点。
     */
    public TreeNode deleteBST(TreeNode tempNode,int target)
    {
        if(tempNode==null) return null;
        else if(tempNode.getThreshold()==target) return tempNode;
        else if(target<tempNode.getThreshold()) return this.deleteBST(tempNode.getLeftchild(), target);
        else return this.deleteBST(tempNode.getRightchild(), target);
    }
    /*
     * 中序遍历
     */
    public void inOrderVisitBST()
    {   
        this.inOrderVisitBST(root);
        System.out.println();
    }
    private void inOrderVisitBST(TreeNode tempNode)
    {   

        if(tempNode!=null)
        {   
            //System.out.println("111");
            this.inOrderVisitBST(tempNode.getLeftchild());
            System.out.print(tempNode.getThreshold()+" ");          
            this.inOrderVisitBST(tempNode.getRightchild()); 
        }   
    }
    public static void main(String[] args)
    {
        Scanner in =new Scanner(System.in);
        int[] initdatas=new int[] {45,12,53,3,37,100,9,24,61,6};
        /*for(int i=0;i<initdatas.length;i++)
        {
            initdatas[i]=in.nextInt();
        }*/
        BiSearchTree bst=new BiSearchTree();
        bst.creatBST(initdatas);
       /* boolean test=bst.getRoot()==null?false:true;
        if(test) System.out.println("111");*/
        bst.inOrderVisitBST();
        bst.deleteBST(45);
        bst.inOrderVisitBST();
    }
}

菜鸟学习中,请大佬指教;别喷的太狠,给点面子谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值