数据结构和算法 之 二叉排序树的查找,删除,遍历,创建

二叉排序树的查找

首先二叉排序树,是将一个无序队列或者数组,循环创建后中序遍历形成有序。
依次和根节点比较,如果相等则返回,如果不相等,则判断左子树和右子树上的值
如果比左子树的值小,则进行左递归查找,如果比右子树的值大,则进行右递归查找。

二叉排序树的删除

分多种情况,如果删除的是叶子节点 则,先找到 parentNode,判断要删除的是左孩子还是右孩子
进行删除

   //是叶子节点,再判断是父节点的 左子节点 还是右子节点
         if(node.getLeft()==null&&node.getRight()==null){
                if(parentNode.getLeft()!=null && parentNode.getLeft().getValue()==value){
                    parentNode.setLeft(null);
                }else if(parentNode.getRight()!=null && parentNode.getRight().getValue()==value){
                    parentNode.setRight(null);
                }

如果要删除的节点不是叶子节点(有一个左孩子或者右孩子),同样先找到parentNode,判断要删除的是左孩子还是右孩子。 分四种情况

//有一颗子树
         else{
             //如果要删除节点的左子树不为空
             if(node.getLeft()!=null){
                 //如果父节点的左子树是 要删除节点
                 if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
                     parentNode.setLeft(node.getLeft());
                 }//如果父节点的右子树是 要删除节点
                 else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
                     parentNode.setRight(node.getLeft());
                 }

             }//如果要删除节点的右子树不为空
             else{
                 //如果父节点的左子树是 要删除节点
                 if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
                     parentNode.setLeft(node.getRight());
                 }//如果父节点右子树是 要删除节点
                 else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
                     parentNode.setRight(node.getRight());
                 }
             }
         }

如果要删除的节点都有左右孩子,则先找到 要删除的节点的左子树的最大值,或者右子树的最小值,进行删除,并修改 要删除节点的值

     }
         }//不是叶子节点有两颗子树
         else if(node.getLeft()!=null&&node.getRight()!=null){

             //判断是父节点的 左孩子还是右孩子
             if(parentNode.getLeft().getValue()==node.value){
            //找右子树的最小节点 删除 并赋给当前要删除的节点 // 也可以找左子树的最大节点
                 Node2 tar = deleteAndReturn(node.getRight());
                 node.setValue(tar.getValue());
             }else{
                 Node2 tar = deleteAndReturn(node.getRight());
                 node.setValue(tar.getValue());
             }

         }

代码如下所示:

package com.wuzhixin.tree;
import java.util.ArrayList;
import java.util.List;


public class BinarySortTree {
    public static void main(String[] args) {
        int []arr = {7,3,10,12,5,1,9};
        List<Node2> nodes = new ArrayList<>();
        Node2 node = null;

        SortTree sortTree = new SortTree();
        for(int i=0;i<arr.length;i++){
            node = new Node2(arr[i]);
           sortTree.add(node);
        }
        sortTree.getRoot().midShow();
        sortTree.getRoot().preShow();
        Node2 node2 = sortTree.getRoot().searchNode(10);
        Node2 parentNode2 = sortTree.getRoot().searchParentNode(10);
        System.out.println("**********************");
        System.out.println(node2);
        System.out.println(parentNode2);
   sortTree.midOrder();
   System.out.println("************************");


   sortTree.deleteNode(1);
   sortTree.deleteNode(5);

   sortTree.deleteNode(3);


   sortTree.midOrder();
    }
}
class SortTree{
    private Node2 root;

    public Node2 getRoot() {
        return root;
    }
    public void setRoot(Node2 root) {
        this.root = root;
    }
    public void add (Node2 node){
        if(root==null){
            root=node;
        }
        else{
            root.add(node);
        }
    }
    //前序遍历
    public void preOrder(){
        if(root==null){
            return;
        }
        root.preShow();
    }
    //中序遍历
    public void midOrder(){
        if(root==null){
            return;
        }else{
            root.midShow();
        }
    }
    //查找要删除的节点
    public Node2 findNode(int value){
        if(root==null){
            return null;
        }
       return root.searchNode(value);
    }
    //查找要删除节点的父节点
    public Node2 findParentNode(int value){
        if(root==null){
            return null;
        }
        return root.searchParentNode(value);
    }
    //删除叶子节点
    public void deleteNode(int value){
        if(root==null){
            return;
        }else {
            root.deleteNode(value);
        }
    }
}
class Node2 {
    private Node2 left;
    private Node2 right;
    private Integer value  ;
    public Node2(Integer value) {
        this.value = value;
    }
   @Override
    public String toString() {
        return value +" "
                ;
    }
    public Node2 getLeft() {
        return left;
    }

    public void setLeft(Node2 left) {
        this.left = left;
    }

    public Node2 getRight() {
        return right;
    }

    public void setRight(Node2 right) {
        this.right = right;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    /**
     * 添加节点的方法,
     * 递归的形式添加节点,满足二叉排序树
     * @param node
     */
    public void add(Node2 node){
        if(node == null){
            return;
        }
        //如果当前加入的节点小于当树的根节点,则向左边添加
        if(node.getValue()<=this.getValue()){
            if(this.getLeft()==null){
                this.setLeft(node);
            }//否则向左递归添加
            else{
                this.getLeft().add(node);
            }
        }else{
            if(this.getRight()==null){
                this.setRight(node);
            }else{
                this.getRight().add(node);
            }
        }
    }
    //前序遍历
    public void preShow(){
        System.out.println(this);
        if(this.getLeft()!=null){
            this.getLeft().preShow();
        }
        if(this.getRight()!=null){
            this.getRight().preShow();
        }
    }
    // 中序遍历
    public void midShow(){
        if(this.getLeft()!=null){
            this.getLeft().midShow();
        }
        System.out.print(this+" ");
        if(this.getRight()!=null){
            this.getRight().midShow();
        }
    }

    public Node2 searchNode(int value){
        //如果当前节点的值 等于
        if(this.value==value){
            return this;
        }else {
            if (this.value > value && this.getLeft() != null) {
                return this.getLeft().searchNode(value);
            }  else if(this.value<value && this.getRight()!=null) {
                return this.getRight().searchNode(value);
            } else{
                return null;
            }
        }
    }

    //查找要删除的父节点
    public Node2 searchParentNode(int value){
        if(this.getLeft()!=null&&this.getLeft().getValue()==value|| this.getRight()!=null&&this.getRight().getValue()==value){
            return this;
        }else if(this.getLeft()!=null&&this.getValue()>value){

            return this.getLeft().searchParentNode(value);

        }else if(this.getRight()!=null&&this.getValue()<value){
            return this.getRight().searchParentNode(value);
        }else{
            return null;
        }
    }

    public void deleteNode(int value){
         Node2 node = this.searchNode(value);
         if(node==null){
             System.out.println("没有该节点,无法删除");
             return;
         }
         Node2 parentNode = this.searchParentNode(value);
         //是叶子节点,再判断是父节点的 左子节点 还是右子节点
         if(node.getLeft()==null&&node.getRight()==null){
                if(parentNode.getLeft()!=null && parentNode.getLeft().getValue()==value){
                    parentNode.setLeft(null);
                }else if(parentNode.getRight()!=null && parentNode.getRight().getValue()==value){
                    parentNode.setRight(null);
                }
         }//不是叶子节点有两颗子树
         else if(node.getLeft()!=null&&node.getRight()!=null){

             //判断是父节点的 左孩子还是右孩子
             if(parentNode.getLeft().getValue()==node.value){
            //找右子树的最小节点 删除 并赋给当前要删除的节点 // 也可以找左子树的最大节点
                 Node2 tar = deleteAndReturn(node.getRight());
                 node.setValue(tar.getValue());
             }else{
                 Node2 tar = deleteAndReturn(node.getRight());
                 node.setValue(tar.getValue());
             }

         }//有一颗子树
         else{
             //如果要删除节点的左子树不为空
             if(node.getLeft()!=null){
                 //如果父节点的左子树是 要删除节点
                 if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
                     parentNode.setLeft(node.getLeft());
                 }//如果父节点的右子树是 要删除节点
                 else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
                     parentNode.setRight(node.getLeft());
                 }

             }//如果要删除节点的右子树不为空
             else{
                 //如果父节点的左子树是 要删除节点
                 if(parentNode.getLeft()!=null&&parentNode.getLeft().getValue()==value){
                     parentNode.setLeft(node.getRight());
                 }//如果父节点右子树是 要删除节点
                 else if(parentNode.getRight()!=null&&parentNode.getRight().getValue()==value){
                     parentNode.setRight(node.getRight());
                 }
             }
         }
    }

    //传入根节点,找到该树的最小节点,并删除 返回
    public Node2 deleteAndReturn(Node2 node){
        Node2 target = node;
        while(target.getLeft()!=null){
            target=target.getLeft();
        }
        deleteNode(target.getValue());
        return target;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值