二叉树层序遍历

时间:2021-09-23 11:23:05

Populating Next Right Pointers in Each Node II

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?

Note:

  • 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:

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

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

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

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中保存下一层的首节点,另一个为下一层的当前遍历节点。采取傀儡节点使得迭代内判断逻辑变少(无需判断首节点是否为空),这种方法比前两种方法更快。

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