给定完美二叉树,反转二叉树的交替级别节点

时间:2014-07-10 11:09:19

标签: java recursion data-structures tree binary-tree

我必须解决以下问题:给定一个完美的二叉树,它在其节点上存储字符,反转奇数级别的节点。问题和解决方案来自这里:http://www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/

我正在尝试实施棘手的解决方案。这是我的代码:

  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;
}

}

想法是遍历树in-order方式,将奇数级别的节点存储在ArrayList res中,然后再次遍历in-order res中的树{1}}方式,对于奇数级别的每个节点,我将其id替换为res中的相应值。在第二次有序遍历时,我保留了字段索引,它告诉我res哪个索引应该获取我的数据。

每当我用index中的数据替换相应节点中的数据时,我会递减index。但是因为它是一个递归,如果我进入递归的上层,{{1}}的值与之前相同,并且我没有正确地更改节点的数据。有人可以建议我怎样才能避免这种情况?我已经包含了逐层打印树级别的方法,因此可以看出该方法无法正常工作。

3 个答案:

答案 0 :(得分:1)

我承认我没看过你的节目,抓住我的是你提到的odd levels并且你正在进行inorder遍历。对我来说这很安静!

如果我要编码,这将是我的方法:

  • 如果我必须在BST中使用,我会选择level-order-traversal BFS简单)并保持跟踪奇怪的水平。

  • 然后,在每个奇数级别上,在deQueue一个节点的值上,我将它与当前节点值交换。 (就是它 !!)

这更节省空间(不需要堆栈空间)并且在O(n)时间内实现

示例:

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

当{1}}为第1级时,enQueue中的5deQueue 20的{​​{1}}。{ / p>

现在,只需检查水平是否为奇数。如果是,则将front ed值与前面的节点值交换!

Queue

答案 1 :(得分:1)

您应该使用java.util.Stack来推送和弹出节点。以下是代码的修改版本:

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;
    }
}

答案 2 :(得分:0)

在调用 reverseLevels()后使用 Collections.reverse(res)。这将颠倒您的ArrayList。

在函数 setLevels()中而不是代码

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

使用下面的代码段。然后就不需要使用索引,因为您想要的元素是第一个元素,然后将其删除。

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