简体   繁体   English

给定完美的二叉树,反转二叉树的备用级别节点

[英]Given a Perfect Binary Tree, reverse the alternate level nodes of the binary tree

I have to solve the following problem: Given a perfect binary tree, that stores characters on its nodes, reverse the nodes on the odd levels. 我必须解决以下问题:给定一个完美的二叉树,该树将字符存储在其节点上,将这些节点反转为奇数级。 The problem and the solution are taken from here: http://www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/ . 问题和解决方案从此处获取: http : //www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/

I am trying to implement the tricky solution. 我正在尝试实施棘手的解决方案。 This is my code: 这是我的代码:

  import java.util.ArrayList;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Queue;


  public class ReverseLevel {
   public static class Node{
    char id;
    Node left;
    Node right;
    public Node(char id){
        this.id = id;
        left = null;
        right = null;
    }
}
static Node root;
static Queue<Node> q;
static int index;
static List<Character> res = new ArrayList<Character>();
public static void main(String[] args) {
    createBT();
    printLevelbyLevel(root);
    reverseLevels(root, 0);
    int n = res.size();
    System.out.println();
    for (int i = 0; i < n; i++) {
        System.out.print(res.get(i) + " ");
    }
    System.out.println();
    setLevels(root, 0, n-1);
    printLevelbyLevel(root);

}
private static void printLevelbyLevel(Node root2) {
    q = new LinkedList<Node>();
    q.add(root);
    Queue<Node> nextLevel = new LinkedList<Node>();
    while(!q.isEmpty()){
        Node n = q.remove();
        printNode(n);
        if(hasLeftChild(n)){
            nextLevel.add(n.left);
        }
        if(hasRightChild(n)){
            nextLevel.add(n.right);
        }
        if(q.isEmpty()){
            System.out.println();
            while(!nextLevel.isEmpty()){
                q.add(nextLevel.poll());
            }
        }
    }
}
private static void reverseLevels(Node root, int level){
    if(root == null){
        return;
    }
    reverseLevels(root.left, level+1);
    if(level%2 == 1){
        res.add(root.id);
    }
    reverseLevels(root.right, level+1);

}
private static void setLevels(Node root, int level, int index){
    if(root == null){
        return;
    }
    setLevels(root.left, level+1, index);
    if(level%2 == 1){
        root.id = res.get(index);
        index--;
    }
    setLevels(root.right, level+1, index);
}


private static boolean hasRightChild(Node n) {
    if(n.right != null)
        return true;
    return false;
}
private static boolean hasLeftChild(Node n) {
    if(n.left != null)
        return true;
    return false;
}
private static void printNode(Node n) {
    System.out.print(n.id + " ");
}
private static void createBT() {
    Node n1 = new Node('a');
    Node n2 = new Node('b');
    Node n3 = new Node('c');
    Node n4 = new Node('d');
    Node n5 = new Node('e');
    Node n6 = new Node('f');
    Node n7 = new Node('g');
    Node n8 = new Node('h');
    Node n9 = new Node('i');
    Node n10 = new Node('g');
    Node n11 = new Node('k');
    Node n12 = new Node('l');
    Node n13 = new Node('m');
    Node n14 = new Node('n');
    Node n15 = new Node('o');
    root = n1;
    n1.left = n2;
    n1.right = n3;
    n2.left = n4;
    n2.right = n5;
    n4.left = n8;
    n4.right = n9;
    n5.left = n10;
    n5.right = n11;
    n3.left = n6;
    n3.right = n7;
    n6.left = n12;
    n6.right = n13;
    n7.left = n14;
    n7.right = n15;
}

} }

The idea is to traverse the tree in-order fashion, store the nodes from odd levels in an ArrayList res and then again traverse the tree in in-order fashion and for each node which is in odd level, I replace its id by the corresponding value in res . 这个想法是in-order遍历树,将奇数级的节点存储在ArrayList res ,然后再次in-order遍历树,对于奇数级的每个节点,我将其id替换为res价值。 While the second in-order traversal, I keep field index, which tells me from which index of res I should take my data. 而第二中序遍历,我一直在外地指标,它告诉我从哪个指标res我应该把我的数据。

Whenever I replace the data in the corresponding node with that from res , I decrement index . 每当我用res的数据替换相应节点中的数据时,我都会减少index However since it is a recursion, if I go in upper levels of the recursion, the value of index gets the same as before, and I don't change the data of the nodes correctly. 但是,由于这是递归,所以如果我进入递归的较高级别,则index的值将与以前相同,并且我无法正确更改节点的数据。 Can someone suggest me how can I avoid this? 有人可以建议我如何避免这种情况吗? I have included methods for printing the tree level by level, so it is visible that the method doesn't work correctly. 我已经包括了逐级打印树的方法,因此可见该方法无法正常工作。

I'll admit i havent read the your program, what caught me was that you mentioned odd levels and you are doing inorder traversal.Thats quiet odd for me! 我承认我还没有阅读您的程序,让我inorder是您提到了odd levels并且您正在执行inorder遍历。

If i would code this, here would be my approach : 如果我要编写代码,这就是我的方法:

  • if i have to work on level 's in BST, i'll go with level-order-traversal ( BFS simply ) and keep a track of odd levels. 如果非要 “的BST的工作,我会去与level-order-traversal (BFS简单 ),并保持奇数水平的轨道。

  • Then,on every odd level, on deQueue ing a value of a node, i'll swap it with the current node value. 然后,在每个奇数级上,在对一个节点的值进行deQueue ,我将其与当前节点值交换。 ( that's it !!) 就是这样 !)

This is more space efficient ( no stack space needed ) and is achieved in O(n) time 这样更节省空间( 不需要堆栈空间 ),并在O(n)时间内实现

Example : 范例:

              10             //Level 0
            /    \
           5      20         //Level 1
         /   \  /   \
        1    3 12   25       //Level 2

When enQueue d for Level-1, You will have 5 in deQueue and 20 at the front of Queue . enQueue d为1级,你将有5deQueue20frontQueue

Now, just check if the level is odd.If yes, then swap the deQueue ed value with the value of node in the front! 现在,只需检查级别是否为奇数,如果是,则将deQueue ed值与前面的node值交换!

5<=>20 in this case

You should use a java.util.Stack to push and pop the nodes. 您应该使用java.util.Stack推送和弹出节点。 Here is a modified version of your code: 这是您的代码的修改后的版本:

public class ReverseLevel {
    public static class Node {
        char id;
        Node left;
        Node right;

        public Node(char id) {
            this.id = id;
            left = null;
            right = null;
        }
    }

    static Node            root;
    static Queue<Node>     q;
    static int             index;
    static Stack<Character> stack = new Stack<Character>();

    public static void main(String[] args) {
        createBT();
        printLevelbyLevel(root);

        reverseLevels(root, 0);

        setLevels(root, 0);
        printLevelbyLevel(root);

    }

    private static void printLevelbyLevel(Node root2) {
        q = new LinkedList<Node>();
        q.add(root);
        Queue<Node> nextLevel = new LinkedList<Node>();
        while (!q.isEmpty()) {
            Node n = q.remove();
            printNode(n);
            if (hasLeftChild(n)) {
                nextLevel.add(n.left);
            }
            if (hasRightChild(n)) {
                nextLevel.add(n.right);
            }
            if (q.isEmpty()) {
                System.out.println();
                while (!nextLevel.isEmpty()) {
                    q.add(nextLevel.poll());
                }
            }
        }
    }

    private static void reverseLevels(Node root, int level) {
        if (root == null) {
            return;
        }
        reverseLevels(root.left, level + 1);
        if (level % 2 == 1) {
            stack.push(root.id);
        }
        reverseLevels(root.right, level + 1);

    }

    private static void setLevels(Node root, int level) {
        if (root == null) {
            return;
        }
        setLevels(root.left, level + 1);
        if (level % 2 == 1) {
            root.id = stack.pop();
        }
        setLevels(root.right, level + 1);
    }

    private static boolean hasRightChild(Node n) {
        if (n.right != null)
            return true;
        return false;
    }

    private static boolean hasLeftChild(Node n) {
        if (n.left != null)
            return true;
        return false;
    }

    private static void printNode(Node n) {
        System.out.print(n.id + " ");
    }

    private static void createBT() {
        Node n1 = new Node('a');
        Node n2 = new Node('b');
        Node n3 = new Node('c');
        Node n4 = new Node('d');
        Node n5 = new Node('e');
        Node n6 = new Node('f');
        Node n7 = new Node('g');
        Node n8 = new Node('h');
        Node n9 = new Node('i');
        Node n10 = new Node('g');
        Node n11 = new Node('k');
        Node n12 = new Node('l');
        Node n13 = new Node('m');
        Node n14 = new Node('n');
        Node n15 = new Node('o');
        root = n1;
        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n4.left = n8;
        n4.right = n9;
        n5.left = n10;
        n5.right = n11;
        n3.left = n6;
        n3.right = n7;
        n6.left = n12;
        n6.right = n13;
        n7.left = n14;
        n7.right = n15;
    }
}

Use Collections.reverse(res) after calling reverseLevels() . 在调用reverseLevels()之后使用Collections.reverse(res This will reverse your ArrayList. 这将反转您的ArrayList。

In the function setLevels() instead of below code 在函数setLevels()中,而不是下面的代码

if(level%2 == 1)
{
   root.id = res.get(index);
   index--;
}

use below snippet. 在以下代码段中使用。 Then there will be no need to use index as the element you want is the first element and you remove it. 这样就不需要使用index了,因为您想要的元素是第一个元素,然后将其删除。

if(level%2 == 1)
{
   root.id = res.get(0);
   res.remove(0);
}

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

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