树轮基础:二叉树

欢迎大家关注我的微信公众号:

树轮基础:二叉树_第1张图片

 

树的定义:

树是数据结构和算法分析与设计中的一种非常重要的结构,由N个结点组成的具有层次结构的模型。
其主要有以下几个特点:
1、有一个根结点,一般称为root结点
2、每一个元素都被称为node
3、除了root结点外,其余的结点都会被分为n个互不相交的集合(子树)


树形结构的基本术语:
结点:树形结构里面的元素
子树:当结点大于1时,其余的结点分为互不相交的集合称为子树
度:一个结点拥有的子树数量称为结点的度
叶子:度为0的结点
孩子:结点的子树的根称为孩子结点
双亲:和孩子结点对应
兄弟:同一个双亲结点
深度:结点的最大层次称为树的深度,计算时间复杂度用
森林:由N个互不相交的树称为森林

 

二叉树(BinaryTree):
一种特殊的树形结构,每个结点最多只有两个子树。
在二叉树的第N层上,最多有2^(N-1)个结点,

如:第2层最多有2个结点,第3层最多有4个结点。
满二叉树:
假设树的深度为M,则有2^M-1个结点的二叉树。

如:树的深度为3,满二叉树的结点数为2^3-1=7

 

二叉树的三种遍历(重点):

树轮基础:二叉树_第2张图片
前序遍历:根结点 -> 左子树 -> 右子树
中序遍历:左子树 -> 根结点 -> 右子树
后序遍历:左子树 -> 右子树 -> 根结点

遍历都是从根结点开始,遇根结点输出。

我们以中序遍历为例子:
首先找到A,A有左子树,找到B。
把B当做子树,找B的左子树,没有返回B,输出B。
然后找B的右子树,找到C。
把C当做子树,找C的左子树,找到D。
D没有子树,所以输出D。
此时C的左子树结束,返回C,输出C。
此时A的左子树全部结束,返回A,输出A。
接下来开始遍历A的右子树。
跟上面步骤一样,不做赘述。
所以中序遍历得出:

B -> D -> C -> A -> E -> H -> G -> K -> F

因此三种遍历方式得出的结果是:

前序遍历:ABCDEFGHK
中序遍历:BDCAEHGKF
后序遍历:DCBHKGFEA

我们来看看代码如何实现:

package com.monkey.springdemo.utils.sort;

class Node{
    private String data;
    private Node leftNode;
    private Node rightNode;

    public Node(String data, Node leftNode, Node rightNode) {
        this.data = data;
        this.leftNode = leftNode;
        this.rightNode = rightNode;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getLeftNode() {
        return leftNode;
    }

    public void setLeftNode(Node leftNode) {
        this.leftNode = leftNode;
    }

    public Node getRightNode() {
        return rightNode;
    }

    public void setRightNode(Node rightNode) {
        this.rightNode = rightNode;
    }
}

public class BinaryTree {

    public static void main(String[] args) {
        Node D = new Node("D",null,null);
        Node H = new Node("H",null,null);
        Node K = new Node("K",null,null);
        Node C = new Node("C",D,null);
        Node B = new Node("B",null,C);
        Node G = new Node("G",H,K);
        Node F = new Node("F",G,null);
        Node E = new Node("E",null,F);
        Node A = new Node("A",B,E);//根结点

        BinaryTree binaryTree = new BinaryTree();
        System.out.print("前序遍历:");
        binaryTree.pre(A);
        System.out.println();
        System.out.print("中序遍历:");
        binaryTree.in(A);
        System.out.println();
        System.out.print("后序遍历:");
        binaryTree.post(A);
    }

    public void print(Node node){
        System.out.print(node.getData());
    }

    //前序遍历:根(输出)-> 左 -> 右
    public void pre(Node root){
        //遍历根结点
        print(root);
        //遍历左子树
        if (root.getLeftNode() != null){
            pre(root.getLeftNode());
        }
        //遍历右子树
        if (root.getRightNode() != null){
            pre(root.getRightNode());
        }
    }

    //中序遍历: 左 -> 根(输出)-> 右
    public void in(Node root){
        //遍历左子树
        if (root.getLeftNode() != null){
            in(root.getLeftNode());
        }
        //遍历根结点
        print(root);
        //遍历右子树
        if (root.getRightNode() != null){
            in(root.getRightNode());
        }
    }

    //后序遍历: 左 -> 右 -> 根(输出)
    public void post(Node root){
        //遍历左子树
        if (root.getLeftNode() != null){
            post(root.getLeftNode());
        }
        //遍历右子树
        if (root.getRightNode() != null){
            post(root.getRightNode());
        }
        //遍历根结点
        print(root);
    }

}

前、中、后的遍历方式,

主要区别在于结点与子树的遍历顺序。

大家搞懂了这个顺序,自然而然就理解了遍历方式。

你可能感兴趣的:(Java,算法)