原题:Populate each next pointer to point to its next right node. If there is no next right node, the next
pointer should be set to NULL
.Initially, all next pointers are set to NULL
.
Note:
- You may only use constant extra space.
- You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every
- parent has two children).
看到这个题第一印象是层次遍历,创建一个线索二叉树,不过有一个非常棘手的问题,即每一行的
最后一个元素不是指向下
一行的第一个元素,而是指向NULL,传统的层次遍历如下:
由于这个题的要求是每一行的最后一个元素的next指向NULL,因此学渣看了别人的算法,用一个NULL来搞定!!!
1 由于层次遍历是用队列来搞定的,在root入队后,再入队一个NULL,让NULL当成一个正常的node来处理,那么利用入队出队的顺序,root自然会指向这个NULL
2 层次遍历时,每次从队头取一个非NULL元素时,将其左右节点都加入这个队列;当队头是NULL时,说明这一行之前的所有元素的左右子节点都入队,然后再入队一个NULL来标志下一行的结束。(关键)
3在层次遍历时,每次都是先把头pop出来之后,然后把这个头的next指向下一个头(由于上一个已经pop出来,下一个自然成为一个头),即使是NULL也没关系,说明把某一行的最后一个元素指向了NULL,符合题意。
4 遇到一个NULL时,有一个例外,即当处理到最后一个NULL时,由于pop出来后,队列会变空,此时结束
如图下:
代码如下:
class Solution {
public:
void connect(TreeLinkNode *root) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(root==NULL) return;
queue<TreeLinkNode*> q;
q.push(root);
//入队一个NULL用来区别每一行的末尾,防止某一行的最后一个元素和下一行第一个元素连接起来
q.push(NULL);
TreeLinkNode * current = root;
while(!q.empty()){
current = q.front();
q.pop();
if(current!=NULL){
//current不为空,则current的next指向队头。。。。。
current->next = q.front();
//如果左节点不为空,则左节点入队
if(current->left!=NULL)
q.push(current->left);
//如果右节点不为空,则右节点入队
if(current->right!=NULL)
q.push(current->right);
}
else {
//如果队列为空,说明已经是在处理最后一个元素,就不能压栈了,否则会无线循环。。。
if(!q.empty())
q.push(NULL);
}
}
}
};