二叉树层序遍历

Populating Next Right Pointers in Each Node IIspa

Follow up for problem "Populating Next Right Pointers in Each Node".指针

What if the given tree could be any binary tree? Would your previous solution still work?code

Note:blog

  • You may only use constant extra space.

 

For example,
Given the following binary tree,队列

         1
       /  \
      2    3
     / \    \
    4   5    7

 

After calling your function, the tree should look like:io

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL

解答:这题主要思路是层序遍历,有三种方法实现。function

一种是使用队列实现,每次记录队列的长度(即每层的元素个数),而后弹出相应个数的元素,在此过程当中进行添加下层元素和完成向右指针。class

public class Solution {
    public void connect(TreeLinkNode root) {
        if (root == null) return;
        Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
        q.add(root);
        while (q.size() != 0) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                TreeLinkNode temp = q.poll();
                if (i != size - 1) temp.next = q.peek();
                if (temp.left != null) q.offer(temp.left);
                if (temp.right != null) q.offer(temp.right);
            }
        }
    }
}

另外一种是采用迭代的方法,这种方法无需实现队列,节省了空间以及入队和出队的操做,效率比队列高。这里采用了三个节点,cur用来记录当前节点,head记录下一层的首节点,prev记录下一层的上一个遍历节点。效率

public class Solution {
    public void connect(TreeLinkNode root) {
        TreeLinkNode cur = root;
        TreeLinkNode head = null;
        TreeLinkNode prev = null;
        while (cur != null) {
            while (cur != null) {
                if (cur.left != null) {
                    if (prev == null) head = cur.left;
                    else prev.next = cur.left;
                    prev = cur.left;
                }
                if (cur.right != null) {
                    if (prev == null) head = cur.right;
                    else prev.next = cur.right;
                    prev = cur.right;
                }
                cur = cur.next;
            }
            cur = head;
            head = null;
            prev = null;
        }
    }
}

第三种方法也是迭代法实现层序遍历。这种方法采用两个节点,一个为傀儡节点,在next中保存下一层的首节点,另外一个为下一层的当前遍历节点。采起傀儡节点使得迭代内判断逻辑变少(无需判断首节点是否为空),这种方法比前两种方法更快。List

public class Solution {
    public void connect(TreeLinkNode root) {
        while(root != null){
            TreeLinkNode tempChild = new TreeLinkNode(0);
            TreeLinkNode currentChild = tempChild;
            while(root!=null){
                if(root.left != null) { currentChild.next = root.left; currentChild = currentChild.next;}
                if(root.right != null) { currentChild.next = root.right; currentChild = currentChild.next;}
                root = root.next;
            }
            root = tempChild.next;
        }
    }
}