二叉排序树

二叉排序树

    二叉排序树: BST,对于二叉树的任何一个非叶子结点,要求左子节点的值比当前节点的值小,右结点的值比当前结点的值大(临界情况,我们可以放在左右都行,但是要尽量避免相同值)
    例如
在这里插入图片描述

    如果我们要在插入一个结点 {2}在这里插入图片描述
    这个就是二叉排序树的数据结构

二叉排序树的创建和遍历(前中后)

    我们就以上图的数组作为结点进行二叉树创建,我们在创建的过程中要考虑值相同的情况,在这我把他存放在了右子节点.node.value<=node.right.value

先来看一下这个树的功能方法structures图

在这里插入图片描述

Node 类属性
		int value;//结点存放值
        Node left;//左结点信息
        Node right;//右结点信息

		public void add(Node node) {//添加结点功能
            if (node == null) {
                return;
            }
            //先判断左子节点是否符合
            if (node.value < this.value) {
                if (this.left == null) {
                    this.left = node;
                } else {
                    this.left.add(node);
                }

            } else {//否则大于等于当前结点值
                if (this.right == null) {
                    this.right = node;
                } else {
                    this.right.add(node);
                }
            }
		//中序表达式
        public void infixOrder() {
            if (this.left != null) {
                this.left.infixOrder();
            }
            System.out.println(this);
            if (this.right != null) {
                this.right.infixOrder();
            }
BST类
		Node root=null;
		public void addNode(Node node) {
            if (root == null) {
                root = node;
                return;
            } else {
                root.add(node);
            }
        }
        //中序表达式
		public void infixOrder() {
            if (root != null) {
                root.infixOrder();
            } else {
                System.out.println("binary tree is none");
            }
        }
二叉排序树删除结点(逻辑性比较强)

    我们以下面这张图为例来分析删除条件
在这里插入图片描述
    上图基本包括了所有判断条件
        1)要删除结点{1},{9},{6},{15}为叶子结点
        2)要删除结点{3},{12}为只有一颗树的结点
        3)要删除结点{其他都是}为有两颗树及以上的结点
    分析

第一种情况:
	通过遍历找到当前要删除结点,直接删除,因为它已经没有子节点了
第二种情况:
	我要删除{3},它有子节点
	1)我们定义一个父节点临时结点,用于存储父节点的左右指针的信息改动值
			所以我们要为它提供方法 Node searchParent(int value);
	2)我们还应该找到当前数据的结点位置,用于存储当前结点值信息
			所以我们要为它提供方法 Node searchTarget(int value) ;
	3)我们判断target结点是parent的子节点是左子结点,还是右子节点.
			if  parent.left!=null && parent.left.value==value
			那么  再去判断target的节点是左结点还是右结点
				if target.left==null&&target.rigth!=null
				那么 我们交换  parent.left=target.rigth
		一共判断四次,其他的我就不写了,逻辑就是这个样子
第三种情况
	我们首先要从它的子树中找到一个最小的节点,进行提上来
		所以我们定义方法:
		public int findMinNode(Node node) {
            Node target = node;
            while (target.left != null) {
                target = target.left;
            }
            delete(target.value);
            return target.value;
        }
	然后我们再去判断条件
		if 左右节点都不为空,那么我们怎么做
		if 左结点不为空,右节点为空,我们怎么做
		if左节点为空,右结点不为空,我们怎么做
		逻辑代码我不分析了,因为比较简单
我们需要注意一个点,就是parent 为空的时候,就是当前节点未父节点,我们直接把root置为空

    下面直接上代码,所有问题都写在一个总类里面了

package com.BinarySortTree;

import java.time.temporal.ValueRange;

/**
 * created by wyl.. on 2019-08-29 下午 05:11
 */
public class BinarySortTree {
    static class Node {
        int value;
        Node left;
        Node right;

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

        @Override
        public String toString() {
            return "Node:" + value +
                    ',';
        }

        public void   find(Node node,int value){
            if (node.value==value){
                System.out.println(value);
            }
            if (node.left!=null){
                node=node.left;
                node.find(node,value);
            }else if (node.right!=null){
                node=node.right;
                node.find(node,value);
            }else {
                System.out.println("没有该值"); ;
            }
        }
        public void add(Node node) {
            if (node == null) {
                return;
            }
            //先判断左子节点是否符合
            if (node.value < this.value) {
                if (this.left == null) {
                    this.left = node;
                } else {
                    this.left.add(node);
                }

            } else {
                if (this.right == null) {
                    this.right = node;
                } else {
                    this.right.add(node);
                }
            }
        }

        //中序表达式
        public void infixOrder() {
            if (this.left != null) {
                this.left.infixOrder();
            }
            System.out.println(this);
            if (this.right != null) {
                this.right.infixOrder();
            }
        }

        /**
         * @param value 要查找值
         * @return 返回值所在结点位置
         */
        public Node searchTarget(int value) {
            if (value == this.value) {
                return this;
            } else if (value < this.value) {
                if (this.left == null) {
                    return null;
                }
                return this.left.searchTarget(value);
            } else {
                if (this.right == null) {
                    return null;
                }
                return this.right.searchTarget(value);
            }
        }

        /**
         * @param value 当前节点
         * @return 父节点
         */
        private Node searchParent(int value) {
            if ((this.left != null && this.left.value == value)
                    || (this.right != null && this.right.value == value)) {
                return this;
            } else {
                if (value < this.value && this.left != null) {
                    return this.left.searchParent(value);
                } else if (value >=/*=的值我们放在了右结点*/ this.value && this.right != null) {
                    return this.right.searchParent(value);
                } else {
//                    System.out.println("没有找到父节点");
                    return null;
                }
            }
        }
    }

    static class BST {
        private Node root = null;

        public BST() {
        }

        public void find(int value){
            if (root==null){
                try {
                    System.out.println("空树");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (root.value == value) {
                System.out.println(value);
            }else {
                root.find(root, value);
            }
        }
        public void addNode(Node node) {
            if (root == null) {
                root = node;
                return;
            } else {
                root.add(node);
            }
        }

        public void infixOrder() {
            if (root != null) {
                root.infixOrder();
            } else {
                System.out.println("binary tree is none");
            }
        }

        /**
         * 找到最小结点的值
         *
         * @param node
         * @return
         */
        public int findMinNode(Node node) {
            Node target = node;
            while (target.left != null) {
                target = target.left;
            }
            delete(target.value);
            return target.value;
        }

        public Node searchTarget(int value) {
            if (root == null) {
                return null;
            } else {
                return root.searchTarget(value);
            }
        }

        public Node seartchParent(int value) {
            if (root == null) {
                return null;
            } else {
                return root.searchParent(value);
            }
        }

        public void delete(int value) {
            if (root == null) {
                return;
            } else {
                Node target = root.searchTarget(value);
                Node parent = root.searchParent(value);

                if (target == null) {
                    return;
                }
                //如果我们发现二叉排序树,只有一个结点, 即 root.left==root.right==null
                //如果我们发现二叉排序树,如果删除的是root结点,parent==null
                if (parent == null) { //结点是root
                    root = null;
                    return;
                } else if (target.left != null && target.right != null) {
                    int cur = findMinNode(target.right);
                    target.value = cur;
                } else if (target.left == null && target.right != null) {
                    int rightMax=findMinNode(target.right);
                    target.value=rightMax;
                } else if (target.left != null && target.right == null) {
                    int leftMax = findMinNode(target.left);
                    target.value=leftMax;
                } else {
                    if (parent.left != null && parent.left.value == value) {
                        parent.left = null;
                    } else if (parent.right != null && parent.right.value == value) {
                        parent.right = null;
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {7, 3, 10, 12, 5, 1, 9, 2};
        BST bst = new BST();
        for (int i = 0; i < arr.length; i++) {
            bst.addNode(new Node(arr[i]));
        }
        bst.infixOrder();
        bst.find(4);
        bst.delete(1);
        bst.infixOrder();
    }
}


二叉树的学习,其实并不难,理清其中逻辑关系,代码很容易写出来。对于二叉树,链表这个都大量运用了递归思想。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值