以非递归方式遍历二叉树(先序遍历 后序遍历 中序遍历)

问题:以非递归方式遍历二叉树(先序遍历 后序遍历 中序遍历)

思路:模拟递归方式的调用,为每个节点创建堆栈Flash,在pop时候判断当前节点是第几次访问,然后决定是否打印当前节点值以及为左右子节点创建堆栈Flash并入栈

    // 模拟递归调用函数栈
    static class Flash{
        private Node node;
        private boolean visited;
        private int count;

        public Flash(Node node, boolean visited) {
            this.node = node;
            this.visited = visited;
        }
        public void setCount(int count){
            this.count = count;
        }
    }
    // 完全模拟递归调用 先序遍历
    public static void fun(Node head){
        if(head == null)
            return;

        Flash flash = new Flash(head, false);
        flash.count = 1;
        Stack<Flash> stack = new Stack<>();
        stack.push(flash);
        while (!stack.isEmpty()){
            Flash cur = stack.pop();
            // 这里使用 visited 替代count
            // 第二次
            /*if(cur.visited){
                if(cur.node.right!=null){
                    stack.push(new Flash(cur.node.right,false));
                }
            }else{
                // 第一次
                System.out.println(cur.node.value);
                cur.visited = true;
                stack.push(cur);
                if(cur.node.left != null){
                    stack.push(new Flash(cur.node.left,false));
                }
            }*/

            // another
            if(cur.count == 1){
                // 第一次访问
                System.out.println(cur.node.value);
                cur.count++;
                stack.push(cur);
                if(cur.node.left != null){
                    Flash flash1 = new Flash(cur.node.left, false);
                    flash1.count = 1;
                    stack.push(flash1);
                }

            }else if (cur.count == 2){
                // 第二次访问
                // 递归方法中,递归调用cur.node.right并返回后,没有后续其他操作,所以这里不用将当前node对应的Flash再次塞入stack
                if(cur.node.right!=null){
                    Flash flash1 = new Flash(cur.node.right, false);
                    flash1.count = 1;
                    stack.push(flash1);
                }
            }else {
                // 第三次访问
                // 线序遍历永远不会到这里
            }
        }
    }

    // 中序遍历
    public static void processin(Node head){
        if(head == null)
            return;
        Stack<Flash> stack = new Stack<>();
        Flash h = new Flash(head, false);
        stack.add(h);
        while (!stack.isEmpty()){
            Flash cur = stack.pop();
            if(!cur.visited){
                cur.visited = true;
                stack.push(cur);
                if(cur.node.left != null){
                    stack.push(new Flash(cur.node.left,false));
                }
            }else{
                System.out.print(cur.node.value+" ");
                if(cur.node.right!=null){
                    stack.push(new Flash(cur.node.right,false));
                }
            }
        }
    }

    // 后续遍历
    public static void funpost(Node head){
        if(head == null)
            return;
        Stack<Flash> stack = new Stack<>();
        Flash h = new Flash(head, false);
        h.setCount(1);
        stack.add(h);
        while (!stack.isEmpty()){
            Flash cur = stack.pop();
            if(cur.count == 1){
                // 第一次访问该节点
                cur.count ++;
                stack.push(cur);
                if(cur.node.left != null){
                    Flash flash = new Flash(cur.node.left, false);
                    flash.count = 1;
                    stack.push(flash);
                }
            } else if(cur.count == 2){
                // 第二次访问当前节点
                cur.count++;
                stack.push(cur);
                if(cur.node.right != null){
                    Flash flash = new Flash(cur.node.right, false);
                    flash.count = 1;
                    stack.push(flash);
                }
            } else{
                // 第三次访问当前节点
                System.out.println(cur.node.value);
            }
        }

    }


// 另外一种遍历方式
public static void pre(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);
			while (!stack.isEmpty()) {
				head = stack.pop();
				System.out.print(head.value + " ");
				if (head.right != null) {
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

	public static void in(Node cur) {
		System.out.print("in-order: ");
		if (cur != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || cur != null) {
				if (cur != null) {
					stack.push(cur);
					cur = cur.left;
				} else {
					cur = stack.pop();
					System.out.print(cur.value + " ");
					cur = cur.right;
				}
			}
		}
		System.out.println();
	}

	public static void pos1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop(); // 头 右 左
				s2.push(head);
				if (head.left != null) {
					s1.push(head.left);
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			// 左 右 头
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

	public static void pos2(Node h) {
		System.out.print("pos-order: ");
		if (h != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(h);
			Node c = null;
			while (!stack.isEmpty()) {
				c = stack.peek();
				if (c.left != null && h != c.left && h != c.right) {
					stack.push(c.left);
				} else if (c.right != null && h != c.right) {
					stack.push(c.right);
				} else {
					System.out.print(stack.pop().value + " ");
					h = c;
				}
			}
		}
		System.out.println();
	}

你可能感兴趣的:(算法,java,算法,二叉树)