java 实现二叉树 前中后序及一棵树的步骤分析

概念(重要)

在这里插入图片描述
节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6
叶子节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I…等节点为叶节点
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点
**根结点:**一棵树中,没有双亲结点的结点;如上图:A
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
**树的高度或深度:**树中节点的最大层次; 如上图:树的高度为4

树与非树(图)的差别

在这里插入图片描述
二叉树

二叉树的遍历-前中后序

根据访问结点操作发生位置命名
1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。 在这里插入图片描述

2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
在这里插入图片描述
3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根 的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

在这里插入图片描述

// 前序遍历 void preOrderTraversal(Node root);
 
// 中序遍历 void inOrderTraversal(Node root);
 
// 后序遍历 void postOrderTraversal(Node root);
 
// 遍历思路-求结点个数 static int size = 0; void getSize1(Node root);
 
// 子问题思路-求结点个数 int getSize2(Node root);
 
// 遍历思路-求叶子结点个数 

static int leafSize = 0; void getLeafSize1(Node root);
 
// 子问题思路-求叶子结点个数 int getLeafSize2(Node root);
 
// 子问题思路-求第 k 层结点个数 int getKLevelSize(Node root);
 
// 查找 val 所在结点,没有找到返回 null // 按照 根 -> 左子树 -> 右子树的顺序进行查找 // 一旦找到,立即返回,不需要继续在其他位置查找 Node find(Node root, int val);

在这里插入图片描述
写代码实现这个树的先序遍历

package java0418;

public class TestTree {
static class Node {
public char val; //数据域
public Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
public Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树

    public Node (char val) {
        this.val = val;

    }
}

static Node build() {
    Node A = new Node('A');
    Node B = new Node('B');
    Node C = new Node('C');
    Node D = new Node('D');
    Node E = new Node('E');
    Node F = new Node('F');
    Node G = new Node('G');

    A.left = B;
    A.right = C;
    B.left = D;
    B.right = E;
    E.left = G;
    C.right = F;
    return A;
}
public static  void preOrder(Node root) {
    if (root == null) {
        return;
    }
    System.out.println(root.val + " ");
    preOrder(root.left);
    preOrder(root.right);
}

public static void main(String[] args) {
    Node root = build();
    preOrder(root);
}

}

还有一个重要的小点,我竟然不知道,实在是太羞耻了。

我在创建节点的时候,写成了双引号,运行时出现了类型转换错误。
我才知道,双引号默认是String型。单引号默认为字符型。
这个错误太低级了。

		Node A = new Node('A');
        Node B = new Node('B');
        Node C = new Node('C');
        Node D = new Node('D');
        Node E = new Node('E');
        Node F = new Node('F');
        Node G = new Node('G');

加入中序程序

//中序遍历
    public  static void inOrder(Node root){
        if (root == null ) {
            return;
        }
        inOrder(root.left);
        System.out.println(root.val + " ");
        inOrder(root.right);
    }

加入后序程序

//后序遍历
    public static void postOrder (Node root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);  //先访问左节点
        postOrder(root.right);  //再访问右节点
        System.out.println(root.val + " ");     //之后访问根节点
    }

其实只要简单的想的话,不一步一步分析,对递归有逻辑清晰的了解。
所谓后序就是先访问左节点,再访问右节点,之后访问根节点。但是由于二叉树的层数不止一层,递归程序会一步步分析往下推进,推到最后一个没有下层节点的左节点,再去找跟它同层同枝丫的右节点,再找到他们两个的根节点,再依次往上推进。
这就是后序,程序非常简单。

//先序遍历
    public static  void preOrder(Node root) {
        if (root == null) {
            return;
        }
        System.out.println(root.val + " ");    
        preOrder(root.left);
        preOrder(root.right);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值