二叉树的遍历与查找

8 篇文章 0 订阅
8 篇文章 0 订阅

二叉树遍历

前、中、后序遍历

在这里插入图片描述

前序遍历:
	1.先输出当前节点
	2.如果左子树不为空,则递归继续前序遍历
	3.如果右子树不为空,则递归继续前序遍历
中序遍历:
	1.如果左子树不为空,则递归继续中序遍历
	2.再输出当前节点
	3.如果右子树不为空,则递归继续中序遍历
后序遍历:
	1.如果左子树不为空,则递归继续后序遍历
	2.如果右子树不为空,则递归继续后序遍历
	3.再输出当前节点
前序遍历
// 前序遍历
    public void preOrder(HeroNode root){
        if (root != null){
            // 先根节点
            System.out.println(root);
            // 再左递归
            preOrder(root.left);
            // 再右递归
            preOrder(root.right);
        }
    }
中序遍历
// 中序遍历
    public void infixOrder(HeroNode root){
        if (root != null){
            // 先左递归
            infixOrder(root.left);
            // 再根节点
            System.out.println(root);
            // 再右递归
            infixOrder(root.right);
        }
    }
后续遍历
// 后序遍历
    public void postOrder(HeroNode root){
        if (root != null){
            // 先左递归
            postOrder(root.left);
            // 再右节点
            postOrder(root.right);
            // 再根节点
            System.out.println(root);
        }
    }
测试
package com.jamin.binarytree;

public class TraverseDemo {
    public static void main(String[] args) {
        // 创建树
        BinaryTree binaryTree = new BinaryTree();
        // 创建节点
        HeroNode root = new HeroNode(1, "Jamin1");
        HeroNode node2 = new HeroNode(2, "Jamin2");
        HeroNode node3 = new HeroNode(3, "Jamin3");
        HeroNode node4 = new HeroNode(4, "Jamin4");
        // 说明:这里手动创建节点,后面学习用递归的方式创建二叉树
        binaryTree.setRoot(root);
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        
        // 前序遍历
        System.out.println("----- 前序遍历 -----");
        binaryTree.preOrder(binaryTree.root);
        // 中序遍历
        System.out.println("----- 中序遍历 -----");
        binaryTree.infixOrder(binaryTree.root);
        // 后序遍历
        System.out.println("----- 后序遍历 -----");
        binaryTree.postOrder(binaryTree.root);
    }
    
}

// 定义二叉树
class BinaryTree{
    public HeroNode root;
    
    public void setRoot(HeroNode root) {
        this.root = root;
    }
    // 前序遍历
    public void preOrder(HeroNode root){
        if (root != null){
            // 先根节点
            System.out.println(root);
            // 再左递归
            preOrder(root.left);
            // 再右递归
            preOrder(root.right);
        }
    }
    // 中序遍历
    public void infixOrder(HeroNode root){
        if (root != null){
            // 先左递归
            infixOrder(root.left);
            // 再根节点
            System.out.println(root);
            // 再右递归
            infixOrder(root.right);
        }
    }
    // 后序遍历
    public void postOrder(HeroNode root){
        if (root != null){
            // 先左递归
            postOrder(root.left);
            // 再右节点
            postOrder(root.right);
            // 再根节点
            System.out.println(root);
        }
    }
}

// 定义树节点
class HeroNode{
    public int no;
    public String name;
    public HeroNode left;
    public HeroNode right;
    
    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }
    public void setLeft(HeroNode left) {
        this.left = left;
    }
    public void setRight(HeroNode right) {
        this.right = right;
    }
    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

输出:

----- 前序遍历 -----
TreeNode{no=1, name='Jamin1'}
TreeNode{no=2, name='Jamin2'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=4, name='Jamin4'}
----- 中序遍历 -----
TreeNode{no=2, name='Jamin2'}
TreeNode{no=1, name='Jamin1'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=4, name='Jamin4'}
----- 后序遍历 -----
TreeNode{no=2, name='Jamin2'}
TreeNode{no=4, name='Jamin4'}
TreeNode{no=3, name='Jamin3'}
TreeNode{no=1, name='Jamin1'}

前、中、后序查找

思路
前序查找:
	1,先判断传入的根节点参数是否为null,如果为null,就返回null,结束查找
	2.如果不为null:
		i.先判断根节点是否是需要查找的节点,如果是就返回根节点并结束查找
		ii.如果不是需要查找的节点,就进行左递归:将左递归的值用一个变量保存起来(用于判断是否需要提前结束查找)
		iii.如果左递归返回的值不为null,则说明左递归已经找到该节点,所以返回该节点并结束查找
		iv.如果左递归返回的值为null,则说明左递归没有找到该节点,所以需要进行右递归,并保存有递归的值
		v.返回右递归的值、结束查找(这里不需要再对返回的值进行判空,因为右递归结束就代表查找结束了)
中序查找:
	参照前序查找:
后序查找:
	参照前序查找:

在这里插入图片描述

前序查找
// 前序遍历查找
    public TreeNode preOrderSearch(TreeNode root,int no){
        if (root == null){  // 如果根节点是Null,则返回Null
            return null;
        }
        if (root.no == no){  // 前序:先判断根节点是否是查找节点
            return root;
        }
        TreeNode resNode = null; // 用于存放查找结果
        if (root.left != null){  // 左节点不为空时,进行左递归
            resNode = preOrderSearch(root.left,no); // 存放递归结果,可能是TreeNode和null
        }
        if (resNode != null){ // 说明左递归已经找到节点:则可以结束查找
            return resNode;
        }
        if (root.right != null){ // 右节点不为空时,进行右递归
            resNode = preOrderSearch(root.right,no);// 存放递归结果,可能是TreeNode和null
        }
        // 这里不需要进行判断了,因为不管resNode的结果是什么,右递归结束时,就必须返回值。
        // 左递归判断的原因是:如果左递归已经找到了,就可以提前结束查找了
        return resNode;
    }
中序查找
// 中序查找
    public TreeNode infixOrderSearch(TreeNode root,int no){
        if (root == null){
            return null;
        }
        TreeNode resNode = null;
        if (root.left != null){
            resNode = infixOrderSearch(root.left, no);
        }
        if (resNode != null){
            return resNode;
        }
        if (root.no == no){
            return root;
        }
        if (root.right != null){
            resNode = infixOrderSearch(root.right, no);
        }
        return resNode;
    }
后序查找
// 后序查找
    public TreeNode postOrderSearch(TreeNode root,int no){
        if (root == null){
            return null;
        }
        TreeNode resNode = null;
        if (root.left != null){
            resNode = postOrderSearch(root.left,no);
        }
        if (resNode != null){
            return resNode;
        }
        if (root.right != null){
            resNode = postOrderSearch(root.right, no);
        }
        if (root.no == no){
            return root;
        }
        return resNode;
    }
测试
package com.jamin.binarytree;

public class BinaryTreeSearchDemo {
    public static void main(String[] args) {
        // 创建树
        BinaryTree1 binaryTree = new BinaryTree1();
        // 创建节点
        TreeNode root = new TreeNode(1, "Jamin1");
        TreeNode node2 = new TreeNode(2, "Jamin2");
        TreeNode node3 = new TreeNode(3, "Jamin3");
        TreeNode node4 = new TreeNode(4, "Jamin4");
        // 说明:这里手动创建节点,后面学习用递归的方式创建二叉树
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        binaryTree.setRoot(root);
        
        // 进行前序查找
        System.out.println("查找结果为: " + binaryTree.preOrderSearch(binaryTree.root,2));
        // 进行中序查找
        System.out.println("查找结果为: " + binaryTree.infixOrderSearch(binaryTree.root,3));
        // 进行后序查找
        System.out.println("查找结果为: " + binaryTree.postOrderSearch(binaryTree.root,4));
        System.out.println("查找结果为: " + binaryTree.postOrderSearch(binaryTree.root,5));
    }
}
class BinaryTree1{
    public TreeNode root;
    
    public void setRoot(TreeNode root) {
        this.root = root;
    }
    
    // 前序遍历查找
    public TreeNode preOrderSearch(TreeNode root,int no){
        if (root == null){  // 如果根节点是Null,则返回Null
            return null;
        }
        if (root.no == no){  // 前序:先判断根节点是否是查找节点
            return root;
        }
        TreeNode resNode = null; // 用于存放查找结果
        if (root.left != null){  // 左节点不为空时,进行左递归
            resNode = preOrderSearch(root.left,no); // 存放递归结果,可能是TreeNode和null
        }
        if (resNode != null){ // 说明左递归已经找到节点:则可以结束查找
            return resNode;
        }
        if (root.right != null){ // 右节点不为空时,进行右递归
            resNode = preOrderSearch(root.right,no);// 存放递归结果,可能是TreeNode和null
        }
        // 这里不需要进行判断了,因为不管resNode的结果是什么,右递归结束时,就必须返回值。
        // 左递归判断的原因是:如果左递归已经找到了,就可以提前结束查找了
        return resNode;
    }
    // 中序查找
    public TreeNode infixOrderSearch(TreeNode root,int no){
        if (root == null){
            return null;
        }
        TreeNode resNode = null;
        if (root.left != null){
            resNode = infixOrderSearch(root.left, no);
        }
        if (resNode != null){
            return resNode;
        }
        if (root.no == no){
            return root;
        }
        if (root.right != null){
            resNode = infixOrderSearch(root.right, no);
        }
        return resNode;
    }
    // 后序查找
    public TreeNode postOrderSearch(TreeNode root,int no){
        if (root == null){
            return null;
        }
        TreeNode resNode = null;
        if (root.left != null){
            resNode = postOrderSearch(root.left,no);
        }
        if (resNode != null){
            return resNode;
        }
        if (root.right != null){
            resNode = postOrderSearch(root.right, no);
        }
        if (root.no == no){
            return root;
        }
        return resNode;
    }
}

// 定义树节点
// 在同一个包下,在遍历那里定义了,所以这里不需要定义了

输出:

查找结果为: TreeNode{no=2, name='Jamin2'}
查找结果为: TreeNode{no=3, name='Jamin3'}
查找结果为: TreeNode{no=4, name='Jamin4'}
查找结果为: null
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jamin624

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值