二叉树的先序遍历、中序遍历、后序遍历:递归 & 循环 两种实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/afei__/article/details/83002941

一、预备知识

首先你得了解 的基本概念,二叉树是每个结点至多只有两个子结点的树,常称之为左右结点。

二叉树的遍历方式有 先序遍历(preorder traeversal)中序遍历(inorder traversal)后序遍历(postorder traversal) 三种,假设结点为 N,左子结点为 L,右子结点为 R。则:

  • 先序遍历:NLR(N 在最前面)
  • 中序遍历:LNR(N 在中间)
  • 后序遍历:LRN(N 在最后面)

 

二、二叉树举例

针对以上这个二叉树,3 种遍历结果为:

先序遍历:0 1 3 7 8 4 9 2 5 6

中序遍历:7 3 8 1 9 4 0 5 2 6

后序遍历:7 8 3 9 4 1 5 6 2 0

 

三、递归实现方式

使用递归是很容易实现二叉树的遍历的。以下是代码示例:

public class Main {

    public static void main(String[] args) {
        TreeNode root = getTestTree(); // 初始化一个二叉树
        preorderTraversal(root); // 先序遍历
        System.out.println();
        inorderTraversal(root); // 中序遍历
        System.out.println();
        postorderTraversal(root); // 后序遍历
    }

    public static void preorderTraversal(TreeNode root) {
        if (root == null) return;
        System.out.print(root.getData() + " ");
        preorderTraversal(root.getLeft());
        preorderTraversal(root.getRight());
    }

    public static void inorderTraversal(TreeNode root) {
        if (root == null) return;
        inorderTraversal(root.getLeft());
        System.out.print(root.getData() + " ");
        inorderTraversal(root.getRight());
    }

    public static void postorderTraversal(TreeNode root) {
        if (root == null) return;
        postorderTraversal(root.getLeft());
        postorderTraversal(root.getRight());
        System.out.print(root.getData() + " ");
    }

    public static TreeNode getTestTree() {
        TreeNode[] nodes = new TreeNode[10];
        for (int i = 0; i < nodes.length; i++) {
            nodes[i] = new TreeNode(i);
        }
        nodes[0].setLeft(nodes[1]);
        nodes[0].setRight(nodes[2]);
        nodes[1].setLeft(nodes[3]);
        nodes[1].setRight(nodes[4]);
        nodes[2].setLeft(nodes[5]);
        nodes[2].setRight(nodes[6]);
        nodes[3].setLeft(nodes[7]);
        nodes[3].setRight(nodes[8]);
        nodes[4].setLeft(nodes[9]);
        return nodes[0];
    }
}

当然,还有一个很简单的 TreeNode 类,如下:

public class TreeNode {
    
    private int data;
    private TreeNode left;
    private TreeNode right;
    
    public TreeNode(int data) {
        this.data = data;
    }

    public int getData() {
        return data;
    }

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

    public TreeNode getLeft() {
        return left;
    }

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

    public TreeNode getRight() {
        return right;
    }

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

执行结果:

0 1 3 7 8 4 9 2 5 6 
7 3 8 1 9 4 0 5 2 6 
7 8 3 9 4 1 5 6 2 0 

 

四、循环实现方式

不使用递归,而使用循环的方式变量二叉树,这是一个比较常见的面试题,实现起来也不会太难。

我们需要用到一个 来帮助我们存储一些结点信息。以下是代码示例:

import java.util.Stack;
 
public class Main {
 
    public static void main(String[] args) {
        TreeNode root = getTestTree(); // 初始化一个二叉树
        preorderTraversal(root); // 先序遍历
        System.out.println();
        inorderTraversal(root); // 中序遍历
        System.out.println();
        postorderTraversal(root); // 后序遍历
    }
     
    public static void preorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        while (current != null || !stack.isEmpty()) {
            if (current != null) {
                System.out.print(current.getData() + " ");
                stack.push(current);
                current = current.getLeft();
            } else {
                current = stack.pop().getRight();
            }
        }
    }
     
    public static void inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        while (current != null || !stack.isEmpty()) {
            if (current != null) {
                stack.push(current);
                current = current.getLeft();
            } else {
                current = stack.pop();
                System.out.print(current.getData() + " ");
                current = current.getRight();
            }
        }
    }
     
    public static void postorderTraversal(TreeNode root) {
        if (root == null) return;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode current = root;
        stack.push(current);
        stack.push(current); // 每个结点 push 两次,这样可以简单的判断出哪些结点是否处理过
        while (!stack.isEmpty()) {
            current = stack.pop();
            if (!stack.isEmpty() && current == stack.peek()) {
                if (current.getRight() != null) {
                    stack.push(current.getRight());
                    stack.push(current.getRight());
                }
                if (current.getLeft() != null) {
                    stack.push(current.getLeft());
                    stack.push(current.getLeft());
                }
            } else {
                System.out.print(current.getData() + " ");
            }
        }
    }
     
    public static TreeNode getTestTree() {
        TreeNode[] nodes = new TreeNode[10];
        for (int i = 0; i < nodes.length; i++) {
            nodes[i] = new TreeNode(i);
        }
        nodes[0].setLeft(nodes[1]);
        nodes[0].setRight(nodes[2]);
        nodes[1].setLeft(nodes[3]);
        nodes[1].setRight(nodes[4]);
        nodes[2].setLeft(nodes[5]);
        nodes[2].setRight(nodes[6]);
        nodes[3].setLeft(nodes[7]);
        nodes[3].setRight(nodes[8]);
        nodes[4].setLeft(nodes[9]);
        return nodes[0];
    }
}

TreeNode 类同上,不再重复贴出,执行结果:

0 1 3 7 8 4 9 2 5 6 
7 3 8 1 9 4 0 5 2 6 
7 8 3 9 4 1 5 6 2 0 

猜你喜欢

转载自blog.csdn.net/afei__/article/details/83002941
今日推荐