您的位置:首页 > Web前端 > Node.js

Populating Next Right Pointers in Each Node

2014-05-15 15:53 218 查看


Problem:Populating Next Right Pointers in Each Node

Given a binary tree:
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).
class Solution {
public:
void connect(TreeLinkNode *root) {
TreeLinkNode * parent_p, *pCur, *leftmost;
if(!root)
return;
parent_p = root;//保存当前结点的父结点
pCur = root->left;//当前处理结点
leftmost = pCur;//指向每一层最左边的结点
while(pCur)
{
if(pCur == parent_p->left)//当前结点是其父结点的左孩子
{
pCur->next = parent_p->right;
pCur = pCur->next;
}
else if(parent_p->next)//当前结点是其父结点的右孩子,并且父结点的next结点存在
{
parent_p =parent_p->next;
pCur->next = parent_p->left;
pCur = pCur->next;
}
else//当前层的所有结点全部处理完,转到下一层继续处理
{
parent_p = leftmost;
leftmost = pCur = parent_p->left;
}
}

}
};

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.
思路1:还是一层一层进行处理,在每一层,总需要查找当前处理结点的next结点;一层处理完之后,总需要查找下一层的第一个非空结点。

这样时间复杂度为O(n),空间复杂度为O(1)。理解起来很简单,就是代码写出来比较繁琐。

class Solution {
public:
void connect(TreeLinkNode *root) {
TreeLinkNode * parent_p, *pCur, *leftmost, *pNext;
int flag_next = 0;//标识pNext是否查找成功
int flag_cur =0;//标识pCur是否查找成功
if(!root || (!root->left && !root->right))//数为空,或者只有一个根结点
return;
parent_p = root;//保存pNext结点的父结点
if(root->left)
pCur = root->left;//当前处理结点
else
pCur = root->right;
leftmost = pCur;//指向每一层最左边的结点
pNext = NULL;
while(pCur)
{
while(parent_p)//找pCur的next结点
{
if(parent_p->left && parent_p->left != pCur)
{//
pNext = parent_p->left;
flag_next = 1;
break;
}
else if(parent_p->right && parent_p->right != pCur)
{
pNext = parent_p->right;
parent_p = parent_p->next;//下次查找要从parent_p的next结开始点找
flag_next = 1;
break;
}
else
parent_p = parent_p->next;
}
if(!flag_next)//这一层没有找到pCur的next结点
{
parent_p = leftmost;
while(parent_p)//找pCur结点
{
if(parent_p->left)
{
pCur = parent_p->left;
flag_cur = 1;
break;
}
else if(parent_p->right)
{
pCur = parent_p->right;
parent_p = parent_p->next;//下次查找要从parent_p的next结开始点找
flag_cur = 1;
break;
}
else
parent_p = parent_p->next;
}
if(!flag_cur)//到达了树的叶子结点层
pCur = NULL;
else//该层的下一层还有结点
{
leftmost = pCur;
flag_cur = 0;
}
}
else//找到了pNext结点
{
flag_next = 0;
pCur->next = pNext;
pCur = pNext;
}
}
}
};
思路2:用迭代的思想,处理完当前结点之后,再一次处理其右子树和左子树。这种实现方法比较巧妙,虽然在时间和空间上并不比上上一种思路好。

class Solution {
public:
void connect(TreeLinkNode *root) {
if (root == NULL) return; // simple
if (root->left == NULL && root->right == NULL) return; // simple
TreeLinkNode* last = root->right; if (last == NULL) last = root->left;
// last means the rightest of the existing sons.
// first means the leftest of the sons of right brothers of the root.
TreeLinkNode* first = root->next;
while (true) {
if (first == NULL) break;
//as far as somne of our right brothers has children we shoudl link our last with it.
if (first->left != NULL) {
last->next = first->left;
break;
}
if (first->right != NULL) {
last->next = first->right;
break;
}
first = first->next;
}
// linking our childrens if both exists
if (root->left != NULL && root->right != NULL) {
root->left->next = root->right;
}

connect(root->right);
connect(root->left);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: