二叉树【Java算法(八)】

写在前面的话: 

  1. 参考资料:《漫画算法》79页 、数据结构课堂上C语言代码
  2. 本章内容:二叉树基础知识,较为简单,请放心食用
  3. IDE:IntelliJ IDEA 2021.2.1
  4. JDK:Java8

 

目录

1.存储方式

1.1 数组

1.2 链式存储

 2.代码实战

 2.1 把线性的链表转换成非线性的二叉树

2.2 通过获取节点,一步步构建二叉树


项目结构:

 

 


是由一个或多个结点组成的有限集合

  1. 必有一个特定的称为根(ROOT)的结点
  2. 剩下的结点被分成n>=0个互不相交的集合T1、T2、......Tn,而且,这些集合的每一个
    又都是树。树T1、T2、......Tn被称作根的子树(Subtree)。 

二叉树,其结点有左右子树之分,二叉树基本上有以下这些情况:

  1. 空二叉树
  2. 只有1个根节点的二叉树
  3. 只有左子树
  4. 只有右子树
  5. 完全二叉树
  6. 满二叉树 

二叉树包含完全二叉树和满二叉树两种特殊形式

 

1.存储方式

存储方式一般有两种:数组链式存储

1.1 数组

二叉树用数组存储,应该将空节点设置成null,如下图。

1.2 链式存储

 遍历方式:

  1. 前序遍历:根左右
  2. 中序遍历:左根右
  3. 后序遍历:左右根
  4. 层次遍历:遍历完一层,才遍历下一层

 2.代码实战

代码构建的二叉树:

 

 

构建二叉树的方式很多,这里主要提两个。

 2.1 把线性的链表转换成非线性的二叉树

BinaryTree.java
package ex01;

/*
    二叉树
 */

import java.util.LinkedList;

public class BinaryTree<E> {

    /*
        二叉树节点
     */
    public static class TreeNode<E>{
        E data;//节点保存的数据
        TreeNode<E> leftChild;//左孩子
        TreeNode<E> rightChild;//右孩子

        TreeNode(E data){
            this.data = data;
        }

    }

    /**
     * 创建一颗二叉树
     * @param list 输入序列
     * @return 返回一棵树
     */
    public <E> TreeNode createBinaryTree(LinkedList<E> list){

        //创建节点
        TreeNode<E> treeNode = null;

        //判断输入序列list是否等于null,或者输入序列list为空
        if(list == null || list.isEmpty()){
            return null;
        }

        //获取list第一个数据
        E data = list.removeFirst();

        //当获取到的是null时,跳过下面语句
        if(data != null){
            //创建一颗二叉树有很多种方式
            // 1.前序遍历创建二叉树
            // 2.中序遍历创建二叉树
            // 3.后序遍历创建二叉树
            // ...

            //这里采用前序遍历的方式创建二叉树
            treeNode = new TreeNode<>(data);
            treeNode.leftChild = createBinaryTree(list);
            treeNode.rightChild = createBinaryTree(list);
        }
        return treeNode;
    }

    /**
     * 前序遍历:根左右
     * @param treeNode 传入一个根节点
     */
    public void formerSequenceTraversal(TreeNode<E> treeNode){

        if(treeNode == null){
            //如果节点为空
            return;
        }

        System.out.print(treeNode.data + "  ");
        formerSequenceTraversal(treeNode.leftChild);
        formerSequenceTraversal(treeNode.rightChild);
    }

    /**
     * 中序遍历:左根右
     * @param treeNode 传入一个根节点
     */
    public void inTheSequenceTraversal(TreeNode<E> treeNode){

        if(treeNode == null){
            //如果节点为空
            return;
        }

        inTheSequenceTraversal(treeNode.leftChild);
        System.out.print(treeNode.data + "  ");
        inTheSequenceTraversal(treeNode.rightChild);
    }

    /**
     * 后序遍历:左右根
     * @param treeNode 传入一个根节点
     */
    public void afterTheSequenceTraversal(TreeNode<E> treeNode){

        if(treeNode == null){
            //如果节点为空
            return ;
        }

        afterTheSequenceTraversal(treeNode.leftChild);
        afterTheSequenceTraversal(treeNode.rightChild);
        System.out.print(treeNode.data + "  ");
    }

}

测试类:TestTree.java

 

package ex01;

/*
    测试二叉树
 */

import java.util.Arrays;
import java.util.LinkedList;

public class TestTree {

    public static void main(String[] args) {

        //按照前序遍历,填充内容
        Integer[] array = new Integer[]{1,2,4,null,null,5,null,null,3,null,6};

        //将数据添加进list当中
        LinkedList<Integer> list = new LinkedList<>(Arrays.asList(array));

        BinaryTree<Integer> binaryTree = new BinaryTree<>();

        //创建二叉树
        BinaryTree.TreeNode root =  binaryTree.createBinaryTree(list);

        //前序遍历
        System.out.println("前序遍历:");
        binaryTree.formerSequenceTraversal(root);
        //中序遍历
        System.out.println("\n中序遍历:");
        binaryTree.inTheSequenceTraversal(root);
        //后序遍历
        System.out.println("\n后序遍历:");
        binaryTree.afterTheSequenceTraversal(root);

    }
}

测试截图:

 

 

2.2 通过获取节点,一步步构建二叉树

二叉树:BinaryTree.java

package ex02;

public class BinaryTree {

    /*
        二叉树节点
     */
    public class Node{

        Integer data;
        Node lChild;
        Node rChild;

        Node(Integer data){
            this.data = data;
        }
    }

    /**
     * 创建二叉树节点
     * @param data 节点中的数据
     * @return 返回一个二叉树节点
     */
    public Node getNode(Integer data){

        //创建一个节点
        Node node = new Node(data);

        return node;
    }

    /**
     * 创建二叉树
     * @return 返回根节点
     */
    public Node getTree(){

        /*
            思路:
                1.要创建一个二叉树,肯定要有节点 ==> 第一步就是获取节点
                2.二叉树不是一个个孤立的节点    ==> 第二部建立联系
                3.返回第一个节点(根节点)
         */

        //1.获取节点
        Node node1 = getNode(1);
        Node node2 = getNode(2);
        Node node3 = getNode(3);
        Node node4 = getNode(4);
        Node node5 = getNode(5);
        Node node6 = getNode(6);

        //2.建立联系
        node1.lChild = node2;
        node1.rChild = node3;

        node2.lChild = node4;
        node2.rChild = node5;

        node3.rChild = node6;

        //3.返回根节点
        return node1;
    }

    /**
     * 前序遍历:根左右
     * @param root 传入根节点
     */
    public void formerSequenceTraversal(Node root){

        if(root == null){
            //如果节点为空
            return;
        }

        System.out.print(root.data + "  ");
        formerSequenceTraversal(root.lChild);
        formerSequenceTraversal(root.rChild);
    }

    /**
     * 中序遍历:左根右
     * @param root 传入根节点
     */
    public void inTheSequenceTraversal(Node root){

        if(root == null){
            //如果节点为空
            return;
        }

        inTheSequenceTraversal(root.lChild);
        System.out.print(root.data + "  ");
        inTheSequenceTraversal(root.rChild);
    }

    /**
     * 后序遍历:左右根
     * @param root 传入根节点
     */
    public void afterTheSequenceTraversal(Node root){

        if(root == null){
            //如果节点为空
            return;
        }

        afterTheSequenceTraversal(root.lChild);
        afterTheSequenceTraversal(root.rChild);
        System.out.print(root.data + "  ");
    }

}

测试类:TestTree.java 

package ex02;

public class TestTree {

    public static void main(String[] args) {

        BinaryTree binaryTree = new BinaryTree();

        BinaryTree.Node root =  binaryTree.getTree();

        System.out.println("前序遍历:");
        binaryTree.formerSequenceTraversal(root);

        System.out.println("\n中序遍历:");
        binaryTree.inTheSequenceTraversal(root);

        System.out.println("\n后序遍历:");
        binaryTree.afterTheSequenceTraversal(root);

    }
}

测试截图:与方法一相同,证明结果正确 

 

完 

 

posted @ 2022-04-09 23:37  辰梦starDream  阅读(7)  评论(0编辑  收藏  举报  来源