简体   繁体   English

“逆序”中二进制树的级别顺序遍历,具有O(n)时间复杂度

[英]Level order traversal of Binary Tree in “Reverse Order” line by line with O(n) time complexity

I want to traverse the given binary tree in reverse order using level order traversal (I have successfully implemented this part, I am unable to add new line after each level) 我想使用级别顺序遍历以相反的顺序遍历给定的二叉树(我已成功实现此部分,我无法在每个级别后添加新行)

在此输入图像描述

The output should be : (need not be in a formatted manner but each level should be in next/new line 输出应该是:(不需要格式化,但每个级别应该在next / new行

 4     5
  2   3
    1

Here is my implementation 这是我的实施

public void levelOrderTraversalInReverseOrderUsingStackAndQueue(Node root) {
    Stack<Node> stack = new Stack<>();
    Queue<Node> queue = new LinkedList<>();
    Node temp;

    queue.add(root);
    while (!queue.isEmpty()) {
        temp = queue.poll();
        stack.push(temp);
        // Enqueue first Right then left because we are storing the end result in stack which is actually LIFO
        if (temp.right != null) {
            queue.add(temp.right);
        }
        if (temp.left != null) {
            queue.add(temp.left);
        }
    }
    while (!stack.isEmpty()) {
        temp = stack.pop();
        System.out.print(temp.data + "\t");
    }
}

Node class 节点类

static class Node {
        int data;
        Node left;
        Node right;

        Node(int data) {
            this.data = data;
        }
    }

Output comes from my implementation 输出来自我的实现

4   5   2   3   1

I thought of adding the null as a delimiter to identify each level, like how I did in Level Order Traversal from Top-to-Bottom but that attempt was not successful, can anyone suggest if this can be achieved. 我想添加null作为分隔符来识别每个级别,就像我在从上到下的Level Order Traversal中所做的那样但是这个尝试没有成功,任何人都可以建议是否可以实现。

Note With recursive solution I was able to add the new line, so there it's not a problem. 注意使用递归解决方案我能够添加新行,所以这不是问题。

The running implementation is here: https://ideone.com/CSShmp 正在运行的实现在这里: https//ideone.com/CSShmp

You just need to modify your loop like this: 你只需要像这样修改你的循环:

    queue.add(root);
    while (!queue.isEmpty()) {
        if (stack.size()>0) {
            stack.push(null);
        }
        int sz = queue.size();
        for (int i=0; i<sz; ++i) {
            temp = queue.poll();
            stack.push(temp);
            // Enqueue first Right then left because we are storing the end result in stack which is actually LIFO
            if (temp.right != null) {
                queue.add(temp.right);
            }
            if (temp.left != null) {
                queue.add(temp.left);
            }
        }
    }

This way you process each level separately and stick nulls in the stack between them. 这样,您可以单独处理每个级别,并在它们之间的堆栈中粘贴空值。

I have changed your code to use 2 queues to marks the levels with a special node with value(-99999). 我已经将代码更改为使用2个队列来标记具有值的特殊节点(-99999)的级别。 It is a standard implementation to identify end of levels. 它是识别级别结束的标准实现 The following code worked for me. 以下代码对我有用。

public void levelOrderTraversalInReverseOrderUsingStackAndQueue(Node root) {
    Stack<Node> stack = new Stack<>();
    Queue<Node> queue1 = new LinkedList<>();
    Queue<Node> queue2 = new LinkedList<>();
    Node temp;

    queue1.add(root);
    while (!queue1.isEmpty() || !queue1.isEmpty()) {

        while (!queue1.isEmpty()) {
            temp = queue1.poll();
            stack.push(temp);
            // Enqueue first Right then left because we are storing the end result in stack which is actually LIFO
            if (temp.right != null) {
                queue2.add(temp.right);
            }
            if (temp.left != null) {
                queue2.add(temp.left);
            }
        }

        stack.push(new Node(-99999));

        while (!queue2.isEmpty()) {
            temp = queue2.poll();
            stack.push(temp);
            // Enqueue first Right then left because we are storing the end result in stack which is actually LIFO
            if (temp.right != null) {
                queue1.add(temp.right);
            }
            if (temp.left != null) {
                queue1.add(temp.left);
            }
        }

        stack.push(new Node(-99999));

    }

    while (!stack.isEmpty()) {
        temp = stack.pop();

        if (temp.data == -99999) {
            System.out.println();
            continue;
        }
        System.out.print(temp.data + "\t");
    }
}

Hope it helps! 希望能帮助到你!

I slightly changed your implementation and used a TreeMap with a custom Comparator to mark levels in reverse order.Although you are not actually traversing in reverse order in the first place, but it still remains O(n). 我稍微改变了你的实现,并使用了一个带有自定义ComparatorTreeMap以相反的顺序标记级别。虽然你实际上并没有以相反的顺序遍历,但它仍然是O(n)。

   public void levelOrderTraversalInReverseOrderUsingStackAndQueue(Node root) {
    Map<Integer,Stack<Node>> levelMap = new TreeMap<>((a,b)->{return -(a-b);});
    Queue<Node> queue = new LinkedList<>();
    Node temp;
    int level = 0;
    queue.add(root);
    levelMap.put(level,new Stack<>());
    levelMap.get(level).push(root);
    while (!queue.isEmpty()) {
        temp = queue.poll();
        if (temp.left != null) {
            level++;
            queue.add(temp.left);
            levelMap.put(level,new Stack<>());
            levelMap.get(level).push(temp.left);
        }
        if (temp.right != null) {
            queue.add(temp.right);
            levelMap.get(level).push(temp.right);
        }
    }
    for (Integer lvl : levelMap.keySet()){
        System.out.print("level "+lvl+"\t:");
        for (Node node: levelMap.get(lvl)){
            System.out.print(node+"\t");
        }
        System.out.println();
    }
}

I also managed to make it work using null separator as you'd like, but I prefer the 1st solution because it is more neat as a concept. 我还设法使用null分隔符使其工作,但我更喜欢第一个解决方案,因为它作为一个概念更整洁。

public static void levelOrderTraversalInReverseOrderUsingStackAndQueue(Node root) {
        Stack<Node> stack = new Stack<>();
        Queue<Node> queue = new LinkedList<>();
        Node temp;

        queue.add(root);
        stack.push(root);
        while (!queue.isEmpty()) {
            temp = queue.poll();
            if (temp.left != null) {
                stack.push(null);
                queue.add(temp.left);
                stack.push(temp.left);
            }
            if (temp.right != null) {
                queue.add(temp.right);
                stack.push(temp.right);
            }

        }
        while (!stack.isEmpty()) {
            temp = stack.pop();
            if (temp == null) {
                System.out.println();
            } else {
                System.out.print(temp.data + "\t");
            }
        }
    }

Hope it helps. 希望能帮助到你。 Choose what best fits your purpose. 选择最适合您目的的产品。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM