面试题 7 :二叉树遍历-前序遍历(DLR),中序遍历(LDR),后序遍历(LRD)-Android端非递归实现

二叉树实体定义:

/**
 * Author: Heynchy
 * Date:   2019/6/24
 * 

* Introduce: 二叉树的定义 */ public class TreeNode implements Serializable { private TreeNode left; // 左子树 private TreeNode right; // 右子树 private String value; // 值 public TreeNode(String value){ this.value = value; } 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; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }

二叉树的初始化:

    /**
     * --------------二叉树--------
     * 

* 1 * / \ * 2 3 * / \ / \ * 4 5 6 7 */ private void initTreeNodes() { mRoot = new TreeNode("1"); TreeNode secondNode = new TreeNode("2"); TreeNode thirdNode = new TreeNode("3"); TreeNode forthNode = new TreeNode("4"); TreeNode fifthNode = new TreeNode("5"); TreeNode sixNode = new TreeNode("6"); TreeNode sevenNode = new TreeNode("7"); mRoot.setLeft(secondNode); mRoot.setRight(thirdNode); secondNode.setLeft(forthNode); secondNode.setRight(fifthNode); thirdNode.setLeft(sixNode); thirdNode.setRight(sevenNode); }

前序遍历(DLR)--非递归实现

    /**
     * 前序遍历---非递归方式
     * 

* 1 2 4 5 3 6 7 * 先访问根节点, 再遍历左子树, 最后遍历右子树 * * @param treeNode */ private void printDLR2(TreeNode treeNode) { // 使用栈进行二叉树的遍历 Stack stacks = new Stack<>(); // 如果栈不为空 或者 根节点不为空 while (!stacks.empty() || treeNode != null) { // 根据当前节点遍历左子树(并将各个节点压栈以便后续遍历右子树) while (treeNode != null) { // 输出值 Log.i("HEYN1234", "treeNode===" + treeNode.getValue()); // 入栈 stacks.push(treeNode); // 遍历左子树 treeNode = treeNode.getLeft(); } // 弹栈并给出节点的右节点 if (!stacks.empty()) { treeNode = stacks.pop(); treeNode = treeNode.getRight(); } } }

中序遍历(LDR)--非递归实现

    /**
     * 中序遍历--非递归实现
     * 4 2 5 1 6 3 7
     * 先遍历左子树,再访问根节点, 最后遍历右子树
     *
     * @param treeNode
     */
    private void printLDR2(TreeNode treeNode) {
        // 使用栈进行二叉树的遍历
        Stack stacks = new Stack<>();
        // 如果栈不为空 或者 根节点不为空
        while (!stacks.empty() || treeNode != null) {
            // 根据当前节点遍历左子树(并将各个节点压栈以便后续遍历右子树)
            while (treeNode != null) {
                // 入栈
                stacks.push(treeNode);
                // 遍历左子树
                treeNode = treeNode.getLeft();
            }
            // 弹栈并给出节点的右节点
            if (!stacks.empty()) {
                treeNode = stacks.pop();
                // 输出值
                Log.i("HEYN1234", "treeNode===" + treeNode.getValue());
                treeNode = treeNode.getRight();
            }
        }
    }

后序遍历(LRD)--非递归实现

   /**
     * 后序遍历
     * 4 5 2 6 7 3 1
     * 先遍历左子树, 然后遍历右子树, 最后访问根节点,
     *
     * @param treeNode
     */
    private void printLRD3(TreeNode treeNode) {
        // 使用栈进行二叉树的遍历
        Stack stacks = new Stack<>();
        TreeNode lastNode = null;
        // 如果栈不为空 或者 根节点不为空
        while (!stacks.empty() || treeNode != null) {
            // 根据当前节点遍历左子树(并将各个节点压栈以便后续遍历右子树)
            while (treeNode != null) {
                // 入栈
                stacks.push(treeNode);
                // 遍历左子树
                treeNode = treeNode.getLeft();
            }
            while (!stacks.empty()) {
                // 此处第一次进入即为最左的节点(4)
                TreeNode node = stacks.pop();
                if (node.getRight() == null || lastNode == node.getRight()) {
                    // 如果该节点没有右子树或者右子树已经遍历过就输出对应的值
                    Log.i("HEYN1234", "treeNode===" + node.getValue());
                    // 将输出值的节点定义为上一个遍历的节点
                    lastNode = node;
                } else {
                    // 如果该节点有右子树并且没有遍历过则对该右子树进行处理

                    // 因为当前出栈的节点node,因为他有右子树且没有遍历,
                    // 所以重新将该节点压入栈,防止数据丢失
                    stacks.push(node);
                    // 将其右子树作为根节点进行遍历
                    treeNode = node.getRight();
                    // 跳出当前循环
                    break;
                }
            }
        }
    }

 

你可能感兴趣的:(移动开发,Android,二叉树遍历,前序遍历,后续遍历,中序遍历,非递归)