二叉树遍历实现:递归和非递归

本文介绍了二叉树的四种遍历方式:先序、中序、后序及层序遍历,并提供了递归和非递归两种实现方法的代码示例。通过具体的Java实现,帮助读者更好地理解和掌握二叉树的遍历算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一个求二叉树公共祖先节点的题用到了后序遍历,临时想起来就总结一下,常见的二叉树遍历方式吧,主要有,先序遍历,中序遍历、后序遍历和层序遍历,每种遍历方式的实现主要有两种:递归和非递归。

其中,非递归算法主要用到了栈和队列(层序遍历)

代码如下,忘了的时候可以看看。

import java.util.LinkedList;


public class BinaryTree {
    //根节点
    private Node<Integer> root;

    //二叉树中节点数量
    private int size;

    //无参构造器
    public BinaryTree() {
        root = new Node<Integer>();
    } 

    //数组构造器
    public BinaryTree(int[] values) {
        System.out.print("新建binaryTree:");
        for (int i : values) {
            System.out.print(i);
        }
        System.out.println();
        boolean isLeft = true;
        int len = values.length;
        if (len == 0)
            return ;
        LinkedList<Node<Integer>> queue = new LinkedList<Node<Integer>>();
        root = new Node<Integer>(values[0]);
        queue.addLast(root);
        Node parent = null;
        Node current = null;
        for (int i=1; i<len; i++) {
            current = new Node<Integer>(values[i]);
            queue.addLast(current);
            if (isLeft)
                parent = queue.getFirst();
            else
                parent = queue.removeFirst();
            if (isLeft) {
                parent.setLeftChild(current);
                isLeft = false;
            }else {
                parent.setRightChild(current);
                isLeft = true;
            }
        }
    } 



    //递归中序遍历
    public void inorder() {
        System.out.print("binaryTree递归中序遍历:");
        inorderTraverseRecursion(root);
        System.out.println();
    }

    //层次遍历
    public void layerorder() {
        System.out.print("binaryTree层次遍历:");
        LinkedList<Node<Integer>> queue = new LinkedList<Node<Integer>>();
        queue.addLast(root);
        Node<Integer> current = null;
        while(!queue.isEmpty()) {
            current = queue.removeFirst();
            if (current.getLeftChild() != null)
                queue.addLast(current.getLeftChild());
            if (current.getRightChild() != null)
                queue.addLast(current.getRightChild());
            System.out.print(current.getValue());
        }
        System.out.println();
    }


    //获得二叉树深度   
    public int getDepth() {
        return getDepthRecursion(root);
    }

    private int getDepthRecursion(Node<Integer> node){
        if (node == null)
            return 0;
        int llen = getDepthRecursion(node.getLeftChild());
        int rlen = getDepthRecursion(node.getRightChild());
        int maxlen = Math.max(llen, rlen);
        return maxlen + 1;
    }
    //递归先序遍历    
    public void preorder() {
        System.out.print("binaryTree递归先序遍历:");
        preorderTraverseRecursion(root);
        System.out.println();
    }



    private void inorderTraverseRecursion(Node<Integer> node) {
        // TODO Auto-generated method stub
        if (node.getLeftChild() != null)
            inorderTraverseRecursion(node.getLeftChild());
        System.out.print(node.getValue());
        if (node.getRightChild() != null)
            inorderTraverseRecursion(node.getRightChild());
    }


    private void preorderTraverseRecursion(Node<Integer> node){
        System.out.print(node.getValue());
        if (node.getLeftChild() != null)
            preorderTraverseRecursion (node.getLeftChild());
        if (node.getRightChild() != null)
            preorderTraverseRecursion (node.getRightChild());
    }

    //非递归先序遍历   
    public void preorderNoRecursion() {
        System.out.print("binaryTree非递归先序遍历:");
        LinkedList<Node<Integer>> stack = new LinkedList<Node<Integer>>();
        stack.push(root);
        Node<Integer> current = null;
        while (!stack.isEmpty()) {
            current = stack.pop();
            System.out.print(current.getValue());
            if (current.getRightChild() != null)
                stack.push(current.getRightChild());
            if (current.getLeftChild() != null)
                stack.push(current.getLeftChild());
        }
        System.out.println();
    }

    /**
     * 非递归中序遍历
     * 栈内保存将要访问的元素
     */
    public void inorderNoRecursion() {
        System.out.print("binaryTree非递归中序遍历:");
        LinkedList<Node<Integer>> stack = new LinkedList<Node<Integer>>();
        Node<Integer> current = root;
        while (current != null || !stack.isEmpty()) {
            while(current != null) {
                stack.push(current);
                current = current.getLeftChild();
            }
            if (!stack.isEmpty()) {
                current = stack.pop();
                System.out.print(current.getValue());
                current = current.getRightChild();
            }
        }
        System.out.println();
    }

    /**
     * 非递归后序遍历

     * 当上一个访问的结点是右孩子或者当前结点没有右孩子则访问当前结点
     */
    public void postorderNoRecursion() {
        System.out.print("binaryTree非递归后序遍历:");
        Node<Integer> rNode = null;
        Node<Integer> current = root;
        LinkedList<Node<Integer>> stack = new LinkedList<Node<Integer>>();
        while(current != null || !stack.isEmpty()) {
            while(current != null) {
                stack.push(current);
                current = current.getLeftChild();
            }
            current = stack.pop();
            while (current != null && (current.getRightChild() == null ||current.getRightChild() == rNode)) {
                System.out.print(current.getValue());
                rNode = current;
                if (stack.isEmpty()){
                    System.out.println();
                    return;
                }
                current = stack.pop();
            }
            stack.push(current);
            current = current.getRightChild();
        }

    }

    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree(new int[]{1,2,3,4,5,6,7,8});
        bt.inorder();
        bt.preorder();
        bt.layerorder();
        bt.preorderNoRecursion();
        bt.inorderNoRecursion();
        bt.postorderNoRecursion();
        System.out.println("深度为:" + bt.getDepth());
    }
}

class Node<V>{
    private V  value;
    private Node<V> leftChild;
    private Node<V> rightChild;

    public Node(){
    };

    public Node(V value) {
        this.value = value;
        leftChild = null;
        rightChild = null;
    }

    public void setLeftChild(Node<V> lNode) {
        this.leftChild = lNode;
    }

    public void setRightChild(Node<V> rNode) {
        this.rightChild = rNode;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    public Node<V> getLeftChild() {
        return leftChild;
    }

    public Node<V> getRightChild() {
        return rightChild;
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值