struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }
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).
For example,
Given the following perfect binary tree,
1 / \ 2 3 / \ / \ 4 5 6 7
After calling your function, the tree should look like:
1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
题目的大意是给定一棵二叉树,并且是完全二叉树,要求把给个结点的next指针指向它同一层的右边的结点,如果结点已经是最右边的结点,就指向空。
由于二叉树是完全二叉树,也就是说每一层都是满的,我们可以利用这个性质,给数的每个结点标号,根节点是1号,按从上到下,从左到右的顺序递增地给每个结点标号,而从上到下,从左到右的顺序就是宽度优先搜索遍历每个结点的顺序,也就是说我们按宽度优先搜索的顺序给每个结点递增地标号,我们就可以根据完全二叉树得到规律,每一层最右边的结点的标号分别是1、3、7、15……这些标号是有规律的,我利用的规律是第n层最右边结点的标号记为i,第n-1层的最右边的结点标号为j,此时i=j*2+1。
算法的具体步骤是利用宽度优先搜索的策略遍历每个结点并按照上述规则给每个结点标号,当前结点的标号用变量index表示,每遍历一个结点时,要先修改上一个结点的next指针,我们用变量emp来标记上一个结点是否是某一层的最右边结点,如果是就把next指针指向空,否则next指针指向当前结点,另外还要比较当前结点是否是某一层最后边的结点,而上一层最右边结点的标号用变量level表示,所以每次只要判断index与level*2+1是否相等,如果当前结点是最右边结点就将变量emp设为真,否则设为假。这样遍历完成以后,除了最后一个结点以外的所有结点的next指针都处理好了,因为最后一个结点肯定是最后一层的最右边的结点,所有最后要把最后一个结点的next指针指向空,这样所有工作就都完成了。
这个算法实际上就是一个宽度优先搜索,所有时间复杂度是O(V+E),由于图是一棵树,所有时间复杂度为O(V)。
以下为源程序:
class Solution {
public:
void connect(TreeLinkNode *root) {
queue<TreeLinkNode*> q;
int index=0;
int level=0;
TreeLinkNode* pre=NULL;
bool emp=false;
if(root==NULL) return;
q.push(root);
while(!q.empty())
{
TreeLinkNode* t=q.front();
q.pop();
index++;
if(pre!=NULL)
{
if(emp) pre->next=NULL;
else pre->next=t;
}
if(level*2+1==index) emp=true,level=index;
else emp=false;
pre=t;
if(t->left!=NULL) q.push(t->left);
if(t->right!=NULL) q.push(t->right);
}
pre->next=NULL;
}
};