• 九、二叉排序数


    1、二叉排序数介绍

     

     回到最初的需求,既然我们已经有了数组和链表这两种数据结构,为什么还需要树这种结构呢?

     

     二叉树的删除,比较复杂

     

     代码实现:

    package com.sorttree;
    
    public class BinarySortTreeDemo {
    
    }
    
    //定义二叉树类
    class BinarySortTree {
        private Node root;
    
        public void setRoot(Node root) {
            this.root = root;
        }
    
        //添加节点的方法
        public void add(Node node) {
            if (root == null) {
                root = node;
            } else {
                root.add(node);
            }
        }
    
        //查找目标值的节点
        public Node search(int value) {
            if (root == null) {
                return null;
            } else {
                return root.search(value);
            }
        }
    
        //查找目标值的父节点
        public Node searchParent(int value) {
            if (root == null) {
                return null;
            } else {
                return root.searchParent(value);
            }
        }
    
        //前序遍历
        public void preOrder() {
            if (this.root != null) {
                this.root.postOrder();
            } else {
                System.out.println("二叉树为空,无法遍历");
            }
        }
    
        //中序遍历
        public void infixOrder() {
            if (this.root != null) {
                this.root.infixOrder();
            } else {
                System.out.println("二叉树为空,无法遍历");
            }
        }
    
        //后序遍历
        public void postOrder() {
            if (this.root != null) {
                this.root.postOrder();
            } else {
                System.out.println("二叉树为空,无法遍历");
            }
        }
    
        //删除节点,比较复杂
        public void delNode(int value) {
            if (root == null) {
                return;
            } else {
                //找到要删除的节点,targetNode
                Node targetNode = search(value);
                if (targetNode == null) {
                    //没有找到该节点
                    return;
                }
                //如果发现这个二叉树只有一个节点,即根节点root
                if (root.left == null && root.right == null) {
                    root = null;
                    return;
                }
                //找到目标值的父节点
                Node parentNode = searchParent(value);
                //1.如果要删除的节点是叶子节点
                if (targetNode.left == null && targetNode.right == null) {
                    //这个时候要判断该节点是左子节点还是右子节点
                    if (parentNode.left != null && parentNode.left.value == value) {
                        parentNode.left = null;
                    } else if (parentNode.right != null && parentNode.right.value == value) {
                        parentNode.right = null;
                    }
                } else if (targetNode.left != null && targetNode.right != null) {
                    //这一步是删除有两颗子树的节点
                    int minVal = delRightTreeMin(targetNode.right);
                    targetNode.value = minVal;
                } else {  //删除只有一颗子树的节点
                    if (targetNode.left != null) {//要删除的节点有左子节点
                        if (parentNode != null) {
                            if (parentNode.left.value == value) {
                                parentNode.left = targetNode.left;
                            } else {
                                parentNode.right = targetNode.left;
                            }
                        } else {
                            root = targetNode.left;
                        }
                    } else {//要删除的节点有右子节点
                        if (parentNode != null) {
                            if (parentNode.left.value == value) {
                                parentNode.left = targetNode.right;
                            } else {
                                parentNode.right = targetNode.right;
                            }
                        } else {
                            root = targetNode.right;
                        }
                    }
                }
    
            }
        }
    
        //以当前node节点为传入的根节点,寻找返回该范围内的最小节点的值,并删除之
        //假象当前的树都是升序树
        public int delRightTreeMin(Node node) {
            Node target = node;
            while (target.left != null) {
                target = target.left;
            }
            delNode(target.value);
            return target.value;
        }
    
    
    }
    
    class Node {
        public int value;
        public Node left;
        public Node right;
    
        public Node(int value) {
            this.value = value;
        }
    
        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    '}';
        }
    
        //二叉排序树和普通二叉树的最大不同,在于添加数据的时候就将数据有序了,也是核心
        public void add(Node node) {
            if (node == null) {
                return;
            }
            if (this.value > node.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 preOrder() {
            System.out.println(this);
            if (this.left != null) {
                this.left.preOrder();
            }
            if (this.right != null) {
                this.right.preOrder();
            }
        }
    
        //中序遍历
        public void infixOrder() {
            if (this.left != null) {
                this.infixOrder();
            }
            System.out.println(this);
            if (this.right != null) {
                this.right.infixOrder();
            }
        }
    
        //后序遍历
        public void postOrder() {
            if (this.left != null) {
                this.left.postOrder();
            }
            if (this.right != null) {
                this.right.postOrder();
            }
            System.out.println(this);
        }
    
        //查找目标值的节点
        public Node search(int value) {
            if (this.value == value) {
                return this;
            } else if (this.value > value) {
                if (this.left == null) {
                    return null;
                }
                return this.left.search(value);
            } else {
                if (this.right == null) {
                    return null;
                }
                return this.right.search(value);
            }
        }
    
        //查找目标值的父节点
        public Node searchParent(int value) {
            if ((this.left != null && this.left.value == value) ||
                    (this.right != null && this.right.value == value)) {
                return this;
            } else {
                if (this.value > value && this.left != null) {
                    return this.left.search(value);
                } else if (this.value < value && this.right != null) {
                    return this.right.search(value);
                } else {
                    return null;
                }
            }
        }
    
    }
  • 相关阅读:
    Ubuntu中安装XAMPP出错的解决方法
    sudo 后不用输入密码的配置
    javascript鼠标双击时触发事件大全
    PHP空值判断
    40音乐海报的创意例子
    35个令人印象深刻的创意404错误页面设计
    35个高分辨率创意苹果桌面壁纸
    38惊人的HD(高清晰度)壁纸七彩的例子
    25精心设计的联系页面例子
    pgpoolII中对 setsockopt 的利用
  • 原文地址:https://www.cnblogs.com/zsy-code/p/13549804.html
Copyright © 2020-2023  润新知