数据结构 ----9.29----树的遍历

140 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

树的遍历无外乎就是前序遍历、中序遍历、后序遍历;而实现遍历的方式有递归、非递归;递归的话对开发相对比较友好,代码量少,但是可读性一般;一般在面试的时候,写出来了递归的遍历实现,面试官都会提出额外的问题考验知识的深度,例如说,既然使用了递归的方式实现,那,你知道递归的弊端吗,可以用非递归的方式实现吗

递归与非递归

递归的话,代码量不多,本质上是栈不断的压栈出栈,在递归次数过大的时候,容易导致栈溢出的问题;可以使用非递归的方式避免栈溢出的问题;同时,可以把递归的方法抽离出来单独调用,同样可以避免栈溢出问题,在单次调用的时候,栈已经销毁,所以不会溢出。

创建树

private static class TreeNode {
int data;
TreeNode leftChild;
TreeNode rightChild;
public TreeNode(int data){
this.data = data;
}

}

后序非递归遍历

  • 初始化一个栈
  • while 循环遍历 当前树不为空,或者栈不为空
  • 取一个变量值,不断抛出栈,并且遍历左子树
  • 如果栈不为空,如果栈顶,则继续右子树遍历
/**
 * 非递归方式遍历后序
 * @param root
 */
public static void postOrderTraveralWithStack(TreeNode root){
    Stack<TreeNode> stack = new Stack<>();
    TreeNode treeNode = root;
    while (treeNode != null || !stack.isEmpty()){
        while (treeNode != null){
            treeNode.isFirst = true;
            stack.push(treeNode);
            treeNode = treeNode.leftChild;
        }
        if (!stack.isEmpty()){
            treeNode = stack.pop();
            //首次出现在栈顶,则证明右节点还未被遍历
            if (treeNode.isFirst){
                treeNode.isFirst = false;
                stack.push(treeNode);
                treeNode = treeNode.rightChild;
            }
            else {
                System.out.println(treeNode.data);
                treeNode = null;
            }
        }

    }
}