二叉树删除节点,方法二

二叉树删除节点

让deleNode节点的左子节点直接顶替deleNode,“让deleNode节点的左子节点的最大节点“指向“delete节点的右子节点”

这两种方法有什么不一样吗,都能实现二叉树的节点删除。

标题下面的是第二种方法
package com.tjetc.Tree;


import com.tjetc.Tree.printer.BinaryTreeInfo;


public class BinarySearchTree implements BinaryTreeInfo {


    //根节点
    private Node root;
    //节点数量
    private int size;


    public void add(int element) {
        Node newNode = new Node(element);
        if (root == null) {
            //如果root是null,那么newNode给root
            root = newNode;
            //size数量+1
            size++;
        } else {
            //从根节点循环搜索树的节点的值跟传入的element比大小,如果节点的值大于element值,向节点的左子节点搜索,反之向右子节点搜索
            //最终搜索到左子节点或右子节点为空为止
            Node currentNode = root;
            Node parent = root;


            while (currentNode != null) {
                //当前节点赋值给parent
                parent = currentNode;
                if (currentNode.element > element) {
                    //左子节点搜索
                    currentNode = currentNode.left;
                } else if (currentNode.element < element) {
                    //右子节点搜索
                    currentNode = currentNode.right;
                } else {
                    //直接返回不执行
                    return;
                }
            }
            newNode.setPreNode(parent);


            //newNOde放到parent的左边还是右边
            if (parent.element > element) {
                //放到左子节点
                parent.left = newNode;
            } else {
                //放到右子节点
                parent.right = newNode;
            }
            size++;
        }
    }




    /**
     * 检索二叉树删除节点
     * <p>
     * 思路1.根据要删除的元素值,从根节点检索到对应的Node节点
     * 2.要删除的节点分三种情况
     * (1)要删除的是叶子节点直接删除
     * (2)要删除的节点右左子节点或者右子节点一个分支,需要判断
     * deleteNOde下一个节点是parent左子节点还是右子节点,
     * (3)要删除的节点右左子节点和右子节点,找出deleteNode的
     * 左子树的最大节点值(右子树的最小值),把最大节点值覆盖要
     * 删除的节点值,又回到了(1)或者(2)
     */


    public void deleteNode(int element) {
        Node currentNode = root;
        while (currentNode.element != element) {
            //当前节点赋值给parent
            if (currentNode.element > element) {
                //左子节点搜索
                currentNode = currentNode.left;
            } else if (currentNode.element < element) {
                //右子节点搜索
                currentNode = currentNode.right;
            } else {
                //直接返回不执行
                return;
            }
        }
        Node preNode = currentNode.preNode;
        if (preNode == null) {
            root = root.right;
            return;
        }
        //要删除的是叶子节点
        if (currentNode.left == null && currentNode.right == null) {
            if (preNode.element > currentNode.element) {
                preNode.left = null;
            } else {
                preNode.right = null;
            }
            //要删除的是有左子节点或者右子节点的节点;
        } else if (currentNode.left == null || currentNode.right == null) {
            //要删除的节点有左子节点
            if (currentNode.right == null) {
                //判断要删除的节点是父节点的左子节点还是右子节点
                if (currentNode.element > preNode.element) {
                    preNode.right = currentNode.left;
                } else {
                    preNode.left = currentNode.left;
                }
            }
            //要删除的节点有右子节点
            if (currentNode.left == null) {
                //判断要删除的节点是父节点的左子节点还是右子节点
                if (currentNode.element < preNode.element) {
                    preNode.left = currentNode.right;
                } else {
                    preNode.right = currentNode.right;
                }
            }
            //要删除的节点同时有左子节点和右子节点
        } else {
            //找左子树最大的覆盖要删除的节点
            Node leftChildMaxNode = currentNode.left;
            while (leftChildMaxNode.right != null) {
                leftChildMaxNode = leftChildMaxNode.right;
            }
            preNode = leftChildMaxNode.preNode;
            currentNode.element = leftChildMaxNode.element;
            preNode.right = leftChildMaxNode.left;
        }
        size--;
    }




    //先序遍历
    public void preorder() {
        //顺序根左右
        preorderTravelsal(root);
    }


    private void preorderTravelsal(Node node) {
        if (node == null) {
            return;
        }
        System.out.println(node.element); //根
        preorderTravelsal(node.left); //左
        preorderTravelsal(node.right); //右
    }


    //中序便利
    public void inorder() {
        //左根右
        inorderTravelsal(root);
    }


    public void inorderTravelsal(Node node) {
        if (node == null) {
            return;
        }
        inorderTravelsal(node.left);
        System.out.println(node.element);
        inorderTravelsal(node.right);
    }


    //后序遍历
    public void postorder() {
        //左右根
        postorderTravelsal(root);
    }




    public void postorderTravelsal(Node node) {
        if (node == null) {
            return;
        }
        postorderTravelsal(node.left);
        postorderTravelsal(node.right);
        System.out.println(node.element);
    }


    /**
     * 返回根节点
     *
     * @return
     */
    @Override
    public Object root() {
        return root;
    }


    /**
     * 打印树需要返回node对应的左子节点
     *
     * @param node
     * @return
     */
    @Override
    public Object left(Object node) {
        return ((Node) node).left;
    }


    /**
     * 打印树需要的node对应的右子节点
     *
     * @param node
     * @return
     */
    @Override
    public Object right(Object node) {
        return ((Node) node).right;
    }


    @Override
    public Object string(Object node) {
        return ((Node) node).element;
    }




    class Node {
        /**
         * 保存数据
         */
        private int element;
        /**
         * 左子节点
         */
        private Node left;
        /**
         * 右子节点
         */
        private Node right;


        private Node preNode;


        public Node getPreNode() {
            return preNode;
        }


        public void setPreNode(Node preNode) {
            this.preNode = preNode;
        }


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


        public int getElement() {
            return element;
        }


        public void setElement(int element) {
            this.element = element;
        }


        public Node getLeft() {
            return left;
        }


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


        public Node getRight() {
            return right;
        }


        public void setRight(Node right) {
            this.right = right;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值