数据结构之二叉树的非递归排序

一、非递归先序遍历

方法:
1、创建一个栈;
2、把根节点入栈;
3、取出栈顶元素,访问这个节点;
4、把当前节点的右子树入栈,左子树入栈(非空);
5、回到3重复执行。

源程序:

 public static void preOrderByLoop(TreeNode root) {
        if (root == null) {
            return;
        }
        // 创建一个栈
        Stack<TreeNode> stack = new Stack<>();
        // 把根节点入闸
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode cur = stack.pop();
            System.out.print(cur);
            if (cur.right != null) {
                stack.push(cur.right);
            }
            if (cur.left != null) {
                stack.push(cur.left);
            }
        }
    }

二、非递归中序遍历

方法:
1、创建一个栈;
2、创建一个引用cur,从root 出发,一路向左跑.遇到的非空节点都入栈,当cur遇到null的时候,就循环结束;
3、取出栈顶元素,并访问(中序的特点就是一路往左找,遇到某个节点的左子树为空,才能访问根节点);
4、让 cur指向该节点的右子树,回到2继续执行。

源程序:

public static void inOrderByLoop(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (true) {
            // 里层循环负责 cur 往左走并入栈这件事
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            // 当上面循环结束, cur 就已经是 null
            // 取出栈顶元素, 并且访问
            if (stack.isEmpty()) {
                // 遍历完了
                break;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val);

            // 让 cur 从 top 的右子树出发重复上述过程
            cur = top.right;
        }
   }

三、非递归后序遍历

方法:
1、创建一个栈;
2、搞一个cur引用,从root出发,一路往左走,遇到非空节点就入栈,遇到空就停止;
3、栈顶元素不能立刻访问!!得先判定一下:
a)如果栈顶的右子树为空,那就能访问该元素了,访问同时出栈;
b)如果栈顶元素的右子树前面已经访问过了,也可以访问该元素;
如果当前元素不能被访问,就让cur指向栈顶的右子树,重复执行2。

源程序:

 public static void postOrderByLoop(TreeNode root) {
        if (root == null) {
            return;
        }
        // 1. 创建一个栈
        Stack<TreeNode> stack = new Stack<>();
        // 2. 创建一个引用 cur, 从 root 出发
        TreeNode cur = root;
        // 使用 prev 表示遍历结果的前一个元素
        TreeNode prev = null;
        while (true) {
            // 3. 让 cur 往左走, 遇到非空节点就入栈
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            // 4. 取出栈顶元素判断下能不能访问
            if (stack.isEmpty()) {
                // 遍历结束了
                break;
            }
            // 此处不能直接 pop, 该节点能不能访问还不知道呢.
            // 必须是访问了才能出栈
            TreeNode top = stack.peek();
            if (top.right == null || top.right == prev) {
                // 都能访问该节点
                System.out.print(top.val);
                stack.pop();
                prev = top; // 更新 prev 的指向
            } else {
                cur = top.right;
            }
        }
    }

三、非递归层序遍历

方法:
1、先把根节点放到队列里;
2、进行出队列操作,并且访问这个节点
3、把当前节点的左子树和右子树再入队列(空树就不管了);
4、回到2继续循环执行。

源程序:

public static void levelOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        // 创建一个队列
        Queue<TreeNode> queue = new LinkedList<>();
        // 把根节点入队列
        queue.offer(root);
        // 循环取队列中的队首元素
        while (true) {
            TreeNode cur = queue.poll();
            if (cur == null) {
                break;
            }
            // 访问当前节点, 直接打印
            System.out.print(cur.val);
            // 把左右子树入队列
            if (cur.left != null) {
                queue.offer(cur.left);
            }
            if (cur.right != null) {
                queue.offer(cur.right);
            }
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值