2020-08-30

二叉树(二叉树遍历与查找):

树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树,二叉树的子节点分为左节点与右节点。

如果该二叉树所有的叶子节点都在最后一层,并且满足结点的总数 = 2^n - 1(n为树的层数),则称为满二叉树。 如果二叉树的所有叶子节点(没有子节点的节点)都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,则称为完全二叉树。

在这里插入图片描述

1、遍历二叉树

前序遍历:先输出父节点,再遍历左子树和右子树。
(1)先输出当前节点(初始的节点为root)
(2)如果左子节点不为空,则递归前序遍历
(3)如果右子节点不为空,则递归前序遍历

中序遍历:先遍历左子树,再输出父节点,再遍历右子树
(1)如果左子节点不为空,则递归中序遍历
(2)输出当前节点(初始的节点为root)
(3)如果右子节点不为空,则递归中序遍历

后序遍历:先遍历左子树,再遍历右子树,最后输出父节点
(1)如果左子节点不为空,则递归后序遍历
(2)如果右子节点不为空,则递归后序遍历
(3)输出当前节点(初始的节点为root)

2、通过遍历查找二叉树结点

编写前序查找结点
思路:

    (1)先判断当前结点是否等于要查找到的,如果是则返回当前结点
    (2)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
    判断左子结点是否等于要查找的,如果是则返回当前结点。
    (3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
    判断右子结点是否等于要查找的,如果是则返回当前结点

编写中序查找结点
思路:

    (1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
    判断左子结点是否等于要查找的,如果是则返回当前结点。
    (2)先判断当前结点是否等于要查找到的,如果是则返回当前结点
    (3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
    判断右子结点是否等于要查找的,如果是则返回当前结点

编写后序查找结点
思路:

        (1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
        判断左子结点是否等于要查找的,如果是则返回当前结点。
        (2)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
        判断右子结点是否等否于要查找的,如果是则返回当前结点
        (3)先判断当前结点是等于要查找到的,如果是则返回当前结点

(1)对以下二叉树进行前序、中序、后序遍历

(2)对以下二叉树进行前序、中序、后续遍历查找

在这里插入图片描述

实现代码:

package com.struct;

import java.util.Scanner;


public class BinaryTreeDemo {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        //手动创建一个树
        Node root = new Node(1, "马一");
        Node node1 = new Node(2, "马二");
        Node node2 = new Node(3, "马三");
        Node node3 = new Node(4, "马四");
        Node node4 = new Node(5, "马五");
        root.setLeft(node1);
        root.setRight(node2);
        node2.setLeft(node4);
        node2.setRight(node3);
        binaryTree.setRoot(root);
//        //前序遍历
//        binaryTree.preOrder();
//        //中序遍历
//        binaryTree.infixOrder();
//        //后序遍历
//        binaryTree.postOrder();
        Scanner scanner = new Scanner(System.in);
        //前序遍历查找
//        System.out.println("前序遍历查找~请输入需要查找用户的ID");
//        int no = scanner.nextInt();
//        Node resNode = binaryTree.preOrderSearch(no);
//        if (resNode != null)
//            System.out.println("找到该结点:no = " + resNode.getNo() + "  name = " + resNode.getName());
//        else
//            System.out.println("没有找到no=%d,此结点" + no);
        //中序遍历查找

//        System.out.println("中序遍历查找~请输入需要查找用户的ID");
//        int no = scanner.nextInt();
//        Node resNode = binaryTree.infixOrderSearch(no);
//        if (resNode != null)
//            System.out.println("找到该结点:no = " + resNode.getNo() + "  name = " + resNode.getName());
//        else
//            System.out.println("没有找到no=%d,此结点" + no);

        System.out.println("后序遍历查找~请输入需要查找用户的ID");
        int no = scanner.nextInt();
        Node resNode = binaryTree.postOrderSearch(no);
        if (resNode != null)
            System.out.println("找到该结点:no = " + resNode.getNo() + "  name = " + resNode.getName());
        else
            System.out.println("没有找到no=%d,此结点" + no);
    }

}
class BinaryTree
{
    private Node root;//定义根结点

    public Node getRoot() {
        return root;
    }

    public void setRoot(Node root) {
        this.root = root;
    }
    //前序遍历
    public void preOrder()
    {
        if (root != null)
            this.root.preOrder();
        else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //中续遍历
    public void infixOrder()
    {
        if (root != null)
            this.root.infixOrder();
        else {
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //后续遍历
    public void postOrder()
    {
        if (root != null)
            this.root.postOrder();
        else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //前序遍历查找
    public Node preOrderSearch(int no)
    {
        //如果根结点不为空,则返回前序遍历查找的结果
        if (root != null)
           return root.preOrderSearch(no);
        else {
            return null;
        }
    }

    //中序遍历查找
    public Node infixOrderSearch(int no)
    {
        //如果根结点不为空,则返回中序遍历查找的结果
        if (root != null)
            return root.infixOrderSearch(no);
        else
            return null;
    }

    //后序遍历查找
    public Node postOrderSearch(int no)
    {
        //如果根结点不为空,则返回后序遍历查找的结果
        if (root != null)
            return this.root.postOrderSearch(no);
        else
            return null;
    }
}



//定义节点类
class Node
{
    private int no;//定义节点编号
    private String name;//定义节点名称
    private Node left;//定义节点左子节点
    private Node right;//定义节点右子节点

    public Node(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    //编写前序遍历
    public void preOrder()
    {
        //首先输出该节点
        System.out.println(this);
        //如果左子节点不为空,则继续递归前序遍历
        if (this.left != null)
            this.left.preOrder();
        //如果右子节点不为空,则继续递归前序遍历
        if (this.right != null)
            this.right.preOrder();
    }

    //编写中序遍历
    public void infixOrder()
    {
        //如果左子节点不为空,则继续递归前序遍历
        if (this.left != null)
            this.left.infixOrder();
        //首先输出该节点
        System.out.println(this);
        //如果右子节点不为空,则继续递归前序遍历
        if (this.right != null)
            this.right.infixOrder();
    }

    //编写后序遍历
    public void postOrder()
    {
        //如果左子节点不为空,则继续递归前序遍历
        if (this.left != null)
            this.left.postOrder();
        //如果右子节点不为空,则继续递归前序遍历
        if (this.right != null)
            this.right.postOrder();
        //首先输出该节点
        System.out.println(this);
    }


    /*编写前序查找结点
        思路:
        (1)先判断当前结点是否等于要查找到的,如果是则返回当前结点
        (2)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
        判断左子结点是否等于要查找的,如果是则返回当前结点。
        (3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
        判断右子结点是否等于要查找的,如果是则返回当前结点
     */

    public Node preOrderSearch(int no)
    {
        System.out.println("前序遍历~~~~~~~~~");
        //判断当前结点是否为等于需查找的
        if (this.no == no)
        {
            return this;
        }
        Node node = null;
        //若没找到,向左递归继续查找
        if (this.left != null)
            node = this.left.preOrderSearch(no);
        if (node != null)//此时说明向左递归已找到
            return node;

        //若没找到,向右递归继续查找
        if (this.right != null)
            node = this.right.preOrderSearch(no);

        return node;
    }

        /*编写中序查找结点
        思路:
        (1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
        判断左子结点是否等于要查找的,如果是则返回当前结点。
        (2)先判断当前结点是否等于要查找到的,如果是则返回当前结点
        (3)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
        判断右子结点是否等于要查找的,如果是则返回当前结点
        */
        public Node infixOrderSearch(int no)
        {
            Node node = null;
            //向左递归查找
            if (this.left != null)
            {
               node =  this.left.infixOrderSearch(no);
            }
            if (node != null)//此时说明已经找到
                return node;
            System.out.println("中序遍历~~~~~~~~~");
            //判断当前结点是否等于要查找的
            if (this.no == no)
                return this;
            //如果没找到,向右递归查找
            if (this.right != null)
                node = this.right.infixOrderSearch(no);
            return node;
        }


         /*编写后序查找结点
        思路:
        (1)向左递归,判断左子结点是否为空,如果不为空,继续前序查找
        判断左子结点是否等于要查找的,如果是则返回当前结点。
        (2)向右递归,判断右子结点是否为空,如果不为空,继续前序查找
        判断右子结点是否等否于要查找的,如果是则返回当前结点
        (3)先判断当前结点是等于要查找到的,如果是则返回当前结点
        */
        public Node postOrderSearch(int no)
        {
            Node node = null;//定义一个空结点
            //向左递归开始查找
            if (this.left != null)
                node = this.left.postOrderSearch(no);

            if (node != null)//此时已找到
                return node;

            //向右递归开始查找
            if (this.right != null)
                node = this.right.postOrderSearch(no);

            if (node != null)//此时已找到
                return node;
            System.out.println("后序遍历~~~~~~~~~");
            //判断当前结点是否等于要查找的
            if (this.no == no)
                return this;
            return node;
        }
}

猜你喜欢

转载自blog.csdn.net/zzFZJ_/article/details/108308940
今日推荐