二叉树的基本实现

二叉树节点

//二叉树节点
    private static class TreeNode{
        int value;
        TreeNode leftChild;
        TreeNode rightChild;

        public TreeNode(int value){
            this.value=value;
            leftChild = null;
            rightChild = null;
        }


        public void display(){
            System.out.print(value+" ");
        }

        @Override
        public String toString() {
            return  "TreeNode-value is "+value;
        }


        public boolean isHasLeftChild(TreeNode root){
            if(root.leftChild!=null)
                return  true;
            else{
                return false;
            }
        }

        public boolean isHasRightChild(TreeNode root){
            if(root.rightChild!=null)
                return  true;
            else{
                return false;
            }
        }
    }

二叉树节点的增加

/**
     * 增加二叉树节点
     * @param root
     * @param value
     * @return
     */
    public TreeNode insertNode(TreeNode root,int value){
        TreeNode current = new TreeNode(value);
        if(root == null){
            root = current;
            return root;
        }

        if(root.value < value){
            if(root.rightChild == null){
                root.rightChild = current;
            }else{
                insertNode(root.rightChild,value);
            }
        }else{
            if(root.leftChild == null){
                root.leftChild = current;
            }else{
                insertNode(root.leftChild,value);
            }
        }
        return root;
    }

二叉树的构造

public TreeNode createBinaryTree(int[] data){
        TreeNode root = null;
        if(data == null) {
            return root;
        }
        BinaryTree tree = new BinaryTree();
        for(int i=0;i<data.length;i++){
            root = tree.insertNode(root,data[i]);
        }
        return root;
    }

二叉树的遍历

/**
     * 先序遍历
     * @param root
     */
    public static void preOrderTravle(TreeNode root){
        if(root == null){
            return;
        }
        root.display();
        preOrderTravle(root.leftChild);
        preOrderTravle(root.rightChild);
    }

    /**
     * 后序遍历
     */
    public static void afterOrderTravle(TreeNode root){
        if(root == null){
            return;
        }
        afterOrderTravle(root.leftChild);
        afterOrderTravle(root.rightChild);
        root.display();
    }

    /**
     * 中序遍历
     */
    public static void inOrderTravle(TreeNode root){
        if(root == null){
            return;
        }
        inOrderTravle(root.leftChild);
        root.display();
        inOrderTravle(root.rightChild);
    }

二分查找

/**
     * 二分查找
     * @param root
     * @param value
     * @return
     */
    public static TreeNode findKey(TreeNode root,int value){
        TreeNode current = root;
        for(;;){
            if(current == null){
                return  current;
            }
            if(current.value == value){
                return current;
            }else if(current.value < value){
                current = current.rightChild;
            }else {
                current = current.leftChild;
            }
        }
    }

查找树中最小值/最大值

/**
     * 查找树中最小值
     * @param root
     * @return
     */
    public static int getMinValue(TreeNode root){
        TreeNode current = root;
        while(current.leftChild != null){
            current = current.leftChild;
        }
        return current.value;
    }

    /**
     * 查找树中最大值
     * @param root
     * @return
     */
    public static int getMaxValue(TreeNode root){
        TreeNode current = root;
        while(current.rightChild != null){
            current = current.rightChild;
        }
        return  current.value;
    }

删除节点

对于二叉搜索树的删除操作,主要是要理解其中的几种情况,写起来还是比较简单的。
当然一开始还是需要判断要删除的节点是否存在于我们的树中,如果要删除的元素都不在树中,就直接返回false;否则,再分为以下四种情况来进行分析:

  1. 要删除的节点无左右孩子
  2. 要删除的节点只有左孩子
  3. 要删除的节点只有右孩子
  4. 要删除的节点有左、右孩子

删除方法解释

对于第一种情况,我们完全可以把它归为第二或者第三种情况,就不用再单独写一部分代码进行处理;
如果要删除的节点只有左孩子,那么就让该节点的父亲结点指向该节点的左孩子,然后删除该节点,返回true;
二叉树的基本实现

如果要删除的节点只有右孩子,那么就让该节点的父亲结点指向该节点的右孩子,然后删除该节点,返回true;
二叉树的基本实现
对于上面这两种情况我们还应该在之前进行一个判断,就是判断这个节点是否是根节点,如果是根节点的话,就直接让根节点指向这个节点的左孩子或右孩子,然后删除这个节点。

最后一种也是最麻烦的一种就是要删除的节点的左右孩子都存在。此时我们的删除方法如下:

  1. 找到该节点的右子树中的最左孩子(也就是右子树中序遍历的第一个节点)
  2. 把它的值和要删除的节点的值进行交换
  3. 然后删除这个节点即相当于把我们想删除的节点删除了,返回true;

二叉树的基本实现

/**
     * 删除节点
     * @param root
     * @param value
     * @return
     */
     public static boolean deleteTreeNode(TreeNode root , int value){
          if(root == null){
              return  false;
          }
         TreeNode parent = null;
         TreeNode current = root;
         //要删除的节点
         TreeNode del = null;
         //查找节点
         while(current != null && current.value != value){
             if(current.value > value){
                 parent = current;
                 current = current.leftChild;
             }else{
                 parent = current;
                 current = current.rightChild;
             }
         }
         //节点若不存在,直接返回false
         if(current == null){
             return false;
         }
         //只有右孩子,则进一步判断该节点是否为根节点
         //若为根节点则直接将根节点设置为将被删除节点的右孩子
         //若不是根节点,则将被删除节点的父节点指向被删除节点的右孩子
         if(current.leftChild == null ){
                //如果current就是根节点,则将当前跟节点的右孩子设置为新的根节点
                if(current == root){
                    root = current.rightChild;

                }
               else if(current == parent.leftChild){
                    parent.leftChild = current.rightChild;

                }
               else{
                    parent.rightChild = current.rightChild;

                }
             //只有左孩子,则进一步判断该节点是否为根节点
             //若为根节点则直接将根节点设置为将被删除节点的左孩子
             //若不是根节点,则将被删除节点的父节点指向被删除节点的左孩子
         }else if(current.rightChild == null){
             if(current == root){
                 root = current.leftChild;

             }
             else if(current == parent.leftChild){
                 parent.leftChild = current.leftChild;

             }else{
                 parent.rightChild = current.leftChild;

             }
         }//左右孩子都不为空
         else if(current.leftChild != null && current.rightChild != null){
             //找到节点右子树的最左节点
             TreeNode left = current.rightChild;
             parent = current;
             for(;left.leftChild != null;left = left.leftChild){
                 parent = left;
             }
             del = left;
             //交换节点的值,把left的值作为current的值
             current.value = left.value;
            //将被删除节点的孩子连接到被删除节点的父节点
             if(parent.leftChild == left){
                 parent.leftChild = left.rightChild;
               
             }else{
                 parent.rightChild = left.rightChild;
             }
         }
         return true;
     }