树结构_BST树(二叉排序树)

【BST树(二叉排序树)】

二叉排序树的本质就是:满足左子节点小于父节点,右子节点大于父节点的树(若有等于情况,我是按添加至右子节点处理的)

这样的树有个优点:中序遍历时输出的数据是按升序排序的。比如上图中序遍历结果:{1,6,9,12,10,16,17,18,25}

核心代码实现:(基础的比如Node类,infixOrder方法等,在这里就不列出了,这里只列举核心功能实现)

【1】Node类中创建add方法,该方法符合BST树建立规则

/**
     * 符合BST树建立规则,左子节点小于父节点,右子节点大于父节点
     * @param newNode 要添加的结点
     */
    public void add(Node newNode){
        if (newNode.getData()<this.getData()){//小了往左放
            if (this.getLeft()==null){
                this.setLeft(newNode);
            }else {
                this.getLeft().add(newNode);
            }
        }else {//大了往右放
            if (this.getRight()==null){
                this.setRight(newNode);
            }else {
                this.getRight().add(newNode);
            }
        }
    }

【2】Node类创建search方法,该方法按照输入的value,查找拥有相同值的结点,并返回该节点

/**
     * 按照输入的value,查找拥有相同值的结点
     * @param value 匹配的值
     * @return 找到返回结点,否则返回空
     */
    public Node search(int value){
        if (this.getData()==value){
            return this;
        }
        if (value<this.getData() && this.getLeft()!=null){
            return this.getLeft().search(value);
        }else if (value>=this.getData() && this.getRight()!=null){
            return this.getRight().search(value);
        }else {
            return null;
        }
    }

【3】Node类创建searchParent方法,用于返回要查找的结点的父节点。该方法将被delete方法调用

/**
     * 按照value,查找到拥有相同值结点的父节点
     * @param value 匹配的值
     * @return 找到返回父节点,否则返回空
     */
    public Node searchParent(int value){
        if ((this.left != null && this.left.getData() == value) || (this.right != null && this.right.getData() == value)){
            return this;
        }
        if (value<this.getData() && this.getLeft()!=null){
            return this.getLeft().searchParent(value);
        }else if (value>=this.getData() && this.getRight()!=null){
            return this.getRight().searchParent(value);
        }else {
            return null;
        }
    }

【4】BinarySortTree类,创建delete方法与delRightMin方法,用于删除结点。

删除结点有多种情况:

1,树中只有一个结点:root置空

2,删除叶子结点:父节点对左或右子节点置空

3,删除含有左右子树的节点:利用delRightMin方法找到节点右子树中的最小值结点,将其删除,并将其值覆盖到节点中

4,删除只含有一个子树的结点:父节点对其重新设置为该节点的对应非空子节点

public void delete(int value){
        if (this.root==null){
            System.out.println("空树");
            return;
        }
        Node result=search(value);
        if (result==null){
            System.out.println("未搜索到");
            return;
        }
        //0.只有一个节点
        if (this.root.getLeft()==null && this.root.getRight()==null){
            this.root=null;
            return;
        }
        Node parent=searchParent(value);
        if (result.getRight()==null && result.getLeft()==null){//1.是叶子结点
            if (parent.getRight().getData()==value){
                parent.setRight(null);
            }else {
                parent.setLeft(null);
            }
        }else if (result.getLeft()!=null && result.getRight()!=null){//2.含有左右子树的结点
            int minValue=delRightMin(result.getRight());
            result.setData(minValue);
        }else {//3.只含有一个子树的结点
            if (parent==null){//若是根节点加一个子节点的情况(父节点为空)
                if (result.getLeft()!=null){
                    this.root=result.getLeft();
                }else {
                    this.root=result.getRight();
                }
                return;
            }if (result.getLeft()!=null){//含有左子树
                if (parent.getLeft().getData()==value){//目标结点是父节点的左节点
                    parent.setLeft(result.getLeft());
                }else {//目标结点是父节点的右结点
                    parent.setRight(result.getLeft());
                }
            }else {//含有右子树
                if (parent.getLeft().getData()==value){
                    parent.setLeft(result.getRight());
                }else {
                    parent.setRight(result.getRight());
                }
            }
        }
    }
    public int delRightMin(Node node){
        Node target = node;
        while (target.getLeft()!=null){
            target=target.getLeft();
        }
        delete(target.getData());
        return target.getData();
    }

完整代码实现:

package cn.dataStructureAndAlgorithm.demo.tree.binarySortTree;
class Node{
    private int data;
    private Node left;
    private Node right;

    public Node(int data) {
        this.data = data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

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

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

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                '}';
    }

    /**
     * 符合BST树建立规则,左子节点小于父节点,右子节点大于父节点
     * @param newNode 要添加的结点
     */
    public void add(Node newNode){
        if (newNode.getData()<this.getData()){//小了往左放
            if (this.getLeft()==null){
                this.setLeft(newNode);
            }else {
                this.getLeft().add(newNode);
            }
        }else {//大了往右放
            if (this.getRight()==null){
                this.setRight(newNode);
            }else {
                this.getRight().add(newNode);
            }
        }
    }
    public void infixOrder(){
        if (this.left!=null){
            this.left.infixOrder();
        }
        System.out.print(this+" ");
        if (this.right!=null){
            this.right.infixOrder();
        }
    }

    /**
     * 按照输入的value,查找拥有相同值的结点
     * @param value 匹配的值
     * @return 找到返回结点,否则返回空
     */
    public Node search(int value){
        if (this.getData()==value){
            return this;
        }
        if (value<this.getData() && this.getLeft()!=null){
            return this.getLeft().search(value);
        }else if (value>=this.getData() && this.getRight()!=null){
            return this.getRight().search(value);
        }else {
            return null;
        }
    }

    /**
     * 按照value,查找到拥有相同值结点的父节点
     * @param value 匹配的值
     * @return 找到返回父节点,否则返回空
     */
    public Node searchParent(int value){
        if ((this.left != null && this.left.getData() == value) || (this.right != null && this.right.getData() == value)){
            return this;
        }
        if (value<this.getData() && this.getLeft()!=null){
            return this.getLeft().searchParent(value);
        }else if (value>=this.getData() && this.getRight()!=null){
            return this.getRight().searchParent(value);
        }else {
            return null;
        }
    }
}
class BinarySortTree{
    private Node root;
    public void add(Node node){
        if (node==null){
            System.out.println("结点为空");
            return;
        }
        if (this.root==null){
            this.root=node;
        }else{
         this.root.add(node);
        }
    }
    public void infixOrder(){
        if (this.root==null){
            System.out.println("根节点为空");
            return;
        }
        this.root.infixOrder();
    }
    public Node search(int value){
        if (root==null){
            System.out.println("空树");
            return null;
        }
        return this.root.search(value);
    }
    public Node searchParent(int value){
        if (this.root==null){
            System.out.println("空树");
            return null;
        }
        return this.root.searchParent(value);
    }
    public void delete(int value){
        if (this.root==null){
            System.out.println("空树");
            return;
        }
        Node result=search(value);
        if (result==null){
            System.out.println("未搜索到");
            return;
        }
        //0.只有一个节点
        if (this.root.getLeft()==null && this.root.getRight()==null){
            this.root=null;
            return;
        }
        Node parent=searchParent(value);
        if (result.getRight()==null && result.getLeft()==null){//1.是叶子结点
            if (parent.getRight().getData()==value){
                parent.setRight(null);
            }else {
                parent.setLeft(null);
            }
        }else if (result.getLeft()!=null && result.getRight()!=null){//2.含有左右子树的结点
            int minValue=delRightMin(result.getRight());
            result.setData(minValue);
        }else {//3.只含有一个子树的结点
            if (parent==null){//若是根节点加一个子节点的情况(父节点为空)
                if (result.getLeft()!=null){
                    this.root=result.getLeft();
                }else {
                    this.root=result.getRight();
                }
                return;
            }if (result.getLeft()!=null){//含有左子树
                if (parent.getLeft().getData()==value){//目标结点是父节点的左节点
                    parent.setLeft(result.getLeft());
                }else {//目标结点是父节点的右结点
                    parent.setRight(result.getLeft());
                }
            }else {//含有右子树
                if (parent.getLeft().getData()==value){
                    parent.setLeft(result.getRight());
                }else {
                    parent.setRight(result.getRight());
                }
            }
        }
    }
    public int delRightMin(Node node){
        Node target = node;
        while (target.getLeft()!=null){
            target=target.getLeft();
        }
        delete(target.getData());
        return target.getData();
    }
}
public class 二叉排序树_binarySortTree {
    public static void main(String[] args) {
        BinarySortTree binarySortTree=new BinarySortTree();
        int[] data=new int[]{10,1};//7,3,10,12,5,1,9,0
        for (int temp:data){
            binarySortTree.add(new Node(temp));
        }
        binarySortTree.infixOrder();
        binarySortTree.delete(10);
        System.out.println();
        binarySortTree.infixOrder();
    }
}
Node{data=0} Node{data=1} Node{data=3} Node{data=5} Node{data=7} Node{data=9} Node{data=10} Node{data=12} 
Node{data=0} Node{data=1} Node{data=3} Node{data=5} Node{data=7} Node{data=9} Node{data=12} 

 


有关树结构的其他内容,见下各链接

【树结构_二叉树基础,顺序存储二叉树,线索化二叉树】

【树结构_堆排序】

【树结构_赫夫曼树,赫夫曼编码,文件解压缩】

【树结构_AVL树(平衡二叉树),红黑树与B系列树简介】

 

【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值