二叉树的递归和非递归方式实现的前中后序遍历(Java版本个人笔记)

背景知识:
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树
eg:
二叉树的递归和非递归方式实现的前中后序遍历(Java版本个人笔记)_第1张图片
本文主要介绍非递归方式
二叉树节点的定义:

class Node {
    private int val;
    private Node left;//左子树
    private Node right;//右子树

    public Node(int val) {
        this.val = val;
    }

    public int getVal() {
        return val;
    }

    public Node getLeft() {
        return left;
    }

    public Node getRight() {
        return right;
    }

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

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

递归方式实现的前中后序遍历

  1. 先序遍历
 public static void preOrder(Node head) {
        if(head == null) return;

        System.out.print(head.getVal()+"-");
        preOrder(head.getLeft());
        preOrder(head.getRight());
    }
  1. 中序遍历
public static void midOrder(Node head) {
        if(head == null) return;

        midOrder(head.getLeft());
        System.out.print(head.getVal()+"-");
        midOrder(head.getRight());
    }
  1. 后序遍历
public static void lastOrder(Node head) {
        if(head == null) return;

        lastOrder(head.getLeft());
        lastOrder(head.getRight());
        System.out.print(head.getVal()+"-");
    }

非递归方式实现前中后序遍历
先序遍历
思路:因为先序遍历的顺序是:头左右,利用一个栈,先将头节点入栈,然后栈不为空时就弹出(pop)节点,弹出就打印,然后先将右孩子节点入栈,再讲左孩子入栈(这样出站的顺序就是先左孩子再右孩子)

public static void preOrderNo(Node rootNode) {
        if(rootNode == null) return;

        Stack<Node> stack = new Stack<>();
        stack.push(rootNode);
        while(!stack.empty()) {
            Node node = stack.pop();
            System.out.print(node.getVal()+"-");
            if(node.getRight() != null) {
                stack.push(node.getRight());
            }

            if(node.getLeft() != null) {
                stack.push(node.getLeft());
            }
        }
    }

中序遍历
思路:从根结点开始依次将其左孩子入栈,直到左孩子为空,为空时就从栈中弹出(pop()方法)节点,弹出就打印,然后拿到弹出节点的右孩子(如果存在),将该右孩子右继续重复上一过程(判断左孩子是否存在,存在就入栈)

    public static void midOrderNo(Node head) {
        if(head == null) return;
        Stack<Node> stack = new Stack<>();

        while(!stack.isEmpty() || head != null) {
            if(head != null) {
                stack.push(head);
                head = head.getLeft();
            } else {
                head = stack.pop();
                System.out.print(head.getVal()+"-");
                head = head.getRight();
            }
        }
    }

后序遍历
思路:定义两个栈,先将头节点入栈,然后栈不为空时开始出栈,弹出一个节点就将该节点放入到另外一个栈中,然后将该节点的左右孩子入栈,入栈顺序按照:先左孩子(如果存在)入栈,再右孩子(如果存在)入栈,然后一直重复以上过程,知道栈为空,然后将另外一个栈依次出栈打印节点,就得到后序遍历

 public static void lastOrderNo(Node head) {
        if(head == null) return ;
        Stack<Node> stack = new Stack<>();
        Stack<Node> stack2 = new Stack<>();
        stack.push(head);

        while(!stack.empty()) {
            Node cur = stack.pop();
            stack2.push(cur);

            if(cur.getLeft() != null) {
                stack.push(cur.getLeft());
            }

            if(cur.getRight() != null) {
                stack.push(cur.getRight());
            }
        }
        while(!stack2.empty()) {
            System.out.print(stack2.pop().getVal()+"-");
        }
    }

测试代码:
树结构:
二叉树的递归和非递归方式实现的前中后序遍历(Java版本个人笔记)_第2张图片

public class MyTree {
    public static void main(String[] args) {
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        node1.setLeft(node2);
        Node node3 = new Node(3);
        node1.setRight(node3);
        Node node4 = new Node(4);
        node2.setLeft(node4);
        Node node5 = new Node(5);
        node2.setRight(node5);
        Node node6 = new Node(6);
        node3.setLeft(node6);
        Node node7 = new Node(7);
        node6.setLeft(node7);
        /*       1
            2         3
         4     5     6
                    7
         */
        //先序遍历 头左右  预期:1 2 4 5 3 6 7
        System.out.println("递归遍历的三种方式:");
        System.out.println("先序遍历");
        preOrder(node1);
        System.out.println('\n'+"========================");
        //中序遍历 左头右  预期:4 2 5 1 7 6 3
        System.out.println("中序遍历");
        midOrder(node1);
        System.out.println('\n'+"========================");
        //后序遍历 左右头 预期: 4 5 2 7 6 3 1
        System.out.println("后序遍历");
        lastOrder(node1);
        System.out.println();
        System.out.println("非递归遍历的三种方式:");

        System.out.println("非递归先序遍历");
        preOrderNo(node1);
        System.out.println('\n'+"========================");

        System.out.println("非递归中序遍历");
        midOrderNo(node1);
        System.out.println('\n'+"========================");

        System.out.println("非递归后序遍历");
        lastOrderNo(node1);
    	}
    }

运行结果:
二叉树的递归和非递归方式实现的前中后序遍历(Java版本个人笔记)_第3张图片

你可能感兴趣的:(数据结构与算法,二叉树,数据结构)