二叉树的代码实现 JAVA 版本

こ雲淡風輕ζ 提交于 2020-02-07 13:14:22

本文主要实现二叉树的简单功能:

(1)二叉树的生成

(2)二叉树的遍历:前序遍历,中序遍历,后序遍历,层次遍历

(3)二叉树的删除

(3)判断节点是否存在的功能

package ds.tree;


import ds.link.Node;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @author : cuantianhou 2019/12/17
 */
public class BinaryTree <T extends Comparable<T>>{

    private Node<T> root;

    private int capacity = 0;

    public T insert(T data){
        /**
         * Step1: 如果该节点为空,将该节点设置为根节点,父节点为空,返回出入值
         *
         * */

        capacity++;

         if(root == null) {
             root  = new Node<T>(data,null);
             return root.data;
         }

        /**
         * Step2:从根节点遍历,插入节点比当前节点小,把当前节点设置为左子节点,然后与左子比较,
         * 插入节点比当前节点大,把当前节点设置为右子节点,然后与右子比较,插入节点和当前节点相等
         * 覆盖并返回当前值
         **/

        //父节点
        Node<T> parent = root;
        //与父节点比较的结果
        int compareResult = 0;
        //临时节点
        Node<T> temp = root;
        while(temp != null){
            parent = temp;
            compareResult = temp.data.compareTo(data);
            if(compareResult == 0){
                capacity--;
                return temp.data = data;
            }else if(compareResult > 0){
                temp = temp.left;
            }else{
                temp = temp.right;
            }
        }



        /** Step3 遍历结束,创建新的节点,看插入值和父节点值的比较结果,
         *返回插入值
         */
        Node<T> insertNode = new Node<T>(data,parent);
        if(compareResult > 0){
            parent.left = insertNode;
        }else {
            parent.right = insertNode;
        }


        return insertNode.data;
    }

    /**
     * 返回根节点
     * @return
     */
    public Node<T> getRoot(){
        return root;
    }

    public int getCapacity(){
        return capacity;
    }

    /**
     * 判断是否为空
     * @return
     */
    public boolean isEmpty(){
        return capacity == 0;
    }

    /**
     * 是否包含某一个元素
     * @param data 数据量
     * @return
     */
    public boolean contains(T data){
        return getNode(data,root) != null;
    }
    /**
     * 判断该值是否存在树中
     * @param item 项
     *
     * @return
     */
    public Node<T> getNode(T item, Node<T> node){
        if(node == null) {return null;}
        int compareResult = node.data.compareTo(item);
        if(compareResult > 0) { return getNode(item,node.left);}
        if(compareResult < 0) { return getNode(item,node.right);}
        return node;
    }


    /**
     * 删除二叉树的节点
     * @param item 节点数据
     * @return
     */

    public boolean remove(T item){
        Node<T> searchNode = getNode(item,root);
        //如果不存在,返回false
        if(searchNode == null) return false;
        Node<T> parentNode = searchNode.parent;
        //容量减1
        capacity--;
        /**
         * case 1: 左右都没有孩子
         */
        if(searchNode.left == null && searchNode.right == null){
            if(searchNode == root) {
                root = null;
                gcHelper(searchNode);
                return true;
            }
            if(parentNode.right == searchNode){
                parentNode.right = null;
                gcHelper(searchNode);
                return true;
            }
            if(parentNode.left == searchNode){
                parentNode.left = null;
                gcHelper(searchNode);
                return true;
            }
        }

        /**
         * case2:只有左节点
         */
        if(searchNode.right == null){
            Node<T> leftNode = searchNode.left;
            if(searchNode == root){
                leftNode.parent = null;
                root = leftNode;
                gcHelper(searchNode);
                return true;
            }
            if(parentNode.left == searchNode){
                parentNode.left = leftNode;
            }else{
                parentNode.right = leftNode;
            }
            leftNode.parent =  parentNode;
            gcHelper(searchNode);
            return true;
        }

        /**
         * case3:只有右节点
         */

        if(searchNode.left == null){
            Node<T> rightNode = searchNode.right;
            if(searchNode == root){
                rightNode.parent = null;
                root = rightNode;
                gcHelper(searchNode);
                return true;
            }
            if(parentNode.left == searchNode){
                parentNode.left = rightNode;
            }else{
                parentNode.right = rightNode;
            }
            rightNode.parent =  parentNode;
            gcHelper(searchNode);
            return true;
        }

        /**
         * case4:有左右节点,关键是找到中继后续节点
         */
        Node<T> targetNode = getTargetNode(searchNode);
        if(searchNode.right == targetNode){
            targetNode.parent = searchNode.parent;
            searchNode.parent.right = targetNode;
        }else{
            searchNode.right.parent = searchNode.parent;
            searchNode.parent.right = searchNode.right;
        }
        targetNode.left = searchNode.left;
        gcHelper(searchNode);
        return  true;
    }

    /**
     * gc回收
     * @param deleteNode
     */
    private  void gcHelper(Node<T> deleteNode){
        deleteNode.parent = null;
        deleteNode.left = null;
        deleteNode.right = null;
    }
    /**
     * 获取中继后续节点
     * @param searchNode 删除的节点
     * @return
     */
    public Node<T> getTargetNode(Node<T> searchNode){
        Node<T> temp = searchNode.right;
        while(temp.left != null){
            temp = temp.left;
        }
        return temp;
    }

    /**
     * 前序遍历 根左右
     */
    public void preTransfer(Node<T> node){
        if(node != null){
            System.out.print(node.data+",");
            preTransfer(node.left);
            preTransfer(node.right);
        }
    }

    /**
     *  中序比遍历 左根右
     * @param node
     */
    public void midTransfer(Node<T> node){
        if(node != null){
            midTransfer(node.left);
            System.out.print(node.data+",");
            midTransfer(node.right);
        }
    }


    /**
     * 后序遍历 左右根
     * @param node
     */
    public void postTransfer(Node<T> node){
        if(node != null){
            postTransfer(node.left);
            postTransfer(node.right);
            System.out.print(node.data+",");
        }
    }


    /**
     * 层次遍历
     * @param node
     */
    public void levelTransfer(Node<T> node){
       // Step1:看根节点是否为空,根节点不空,输出根节点的数据
        // Step2: 判断左右的节点是否为空,不空,记录节点信息,进行下次判断
        // Step3: 队列为空时退出循环
        if(null == node) return;
        LinkedList<Node<T>> levelNode = new LinkedList<>();
        levelNode.add(node);
        while(true) {
            int size = levelNode.size();
            if (size != 0) {
                for (int i = 0; i < size; i++) {
                    Node<T> tempNode = levelNode.poll();
                    System.out.print(tempNode.data + ",");
                    if (tempNode.left != null) {
                        levelNode.add(tempNode.left);
                    }
                    if (tempNode.right != null) {
                        levelNode.add(tempNode.right);
                    }
                }
            }else {
                break;
            }
        }
    }

    /**
     * 清空树
     */
    public void clear(){
        clear(root);
        root = null;
    }


    /**
     * 清空树
     * @param node 节点
     */
    private void clear(Node<T> node){
        if(node != null){
            clear(node.left);
            node.left = null;
            clear(node.right);
            node.right= null;
        }
    }

    /**
     * 节点的数据结构
     * @param <T>
     */
    private static final class Node <T extends Comparable<T>>{
        private T data;

        private Node left;

        private Node right;

        private Node parent;

        public Node(T data,Node parent){
            this.data = data;
            this.parent = parent;
        }
    }
}

测试程序:

package ds.tree;

/**
 * @author : cuantianhou 2019/12/18
 */
public class MainApplication {

    public static void main(String[] args) {
        BinaryTree<Integer> binaryTree = new BinaryTree<>();
        //放数据
        binaryTree.insert(73);
        binaryTree.insert(22);
        binaryTree.insert(532);
        binaryTree.insert(62);
        binaryTree.insert(72);
        binaryTree.insert(243);
        binaryTree.insert(42);
        binaryTree.insert(3);
        binaryTree.insert(12);
        binaryTree.insert(52);

        System.out.println("size: " + binaryTree.getCapacity());
        binaryTree.insert(52);
        System.out.println("添加相同元素后的size: " + binaryTree.getCapacity());
        //判断数据是否存在
        System.out.println("数据是否存在:" + binaryTree.contains(12));
        //中序遍历
        System.out.print("中序遍历结果: ");
        binaryTree.midTransfer(binaryTree.getRoot());
        System.out.println();
        //前序遍历
        System.out.print("前遍历结果: ");
        binaryTree.preTransfer(binaryTree.getRoot());
        System.out.println();
        //后序遍历
        System.out.print("后续遍历结果: ");
        binaryTree.postTransfer(binaryTree.getRoot());
        System.out.println();
        //层次遍历
        System.out.print("层次遍历结果: ");
        binaryTree.levelTransfer(binaryTree.getRoot());

        //删除数据
        System.out.println();
        binaryTree.remove(3);
        //后序遍历
        System.out.print("后续遍历结果: ");
        binaryTree.postTransfer(binaryTree.getRoot());
        System.out.println();
        System.out.println("删除数据后判断是否存在:" + binaryTree.contains(3));
        //清空二叉树
        binaryTree.clear();
        System.out.print("清空数据后中序遍历: ");
        binaryTree.midTransfer(binaryTree.getRoot());
    }
}

测试结果:

参考文章:

  1. https://www.jianshu.com/p/bf73c8d50dc2
  2. https://www.cnblogs.com/pszp/p/9845983.html
  3. https://www.cnblogs.com/rainple/p/9970760.html
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!