题目:
给定一个二叉树
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
示例:
输入:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":null,"next":null,"right":{"$id":"6","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}
输出:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":null,"right":null,"val":7},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"6","left":null,"next":null,"right":{"$ref":"5"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"6"},"val":1}
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。
第一种思路:层次遍历二叉树,将每层各个节点的next都指向下一个节点,每层最后一个节点next指向NULL。
Node* connect(Node* root)
{
if(root==NULL)
return root;
queue<Node*> level;
level.push(root);
int len = 0;
while(level.size()!=0)
{
len = level.size();
//处理一层的节点
for(int i=0;i<len;i++)
{
Node* node = level.front();
level.pop();
if(i==len-1)
node->next = NULL;
else
node->next = level.front();
//为了顺序正常,先左后右
if(node->left!=NULL)
level.push(node->left);
if(node->right!=NULL)
level.push(node->right);
}
}
return root;
}
第二种思路:和“填充每个节点的下一个右侧节点指针”思路一样,但是这次所给的树不是完美二叉树,所以如果root->left存在,如果root->right也存在,那么root->left->next为root->right,如果root->right不存在,此时root->left->next为root->left的第一个堂兄弟节点;如果root->right存在,那么root->right->next为root->right的第一个堂兄弟节点。
PS:要特别注意一点,一定要先遍历右子树再遍历左子树,从后往前连接,因为要找节点的第一个堂兄弟节点必须保证父节点及父节点之后的同层节点全部连接完毕才能找到堂兄弟节点。如果不是特别明白可以看下面这张图,这张图就是先遍历左子树后遍历右子树造成的错误。
//寻找第一个堂兄弟节点
Node* getNext(Node* root)
{
Node* temp = root;
while(temp->next)
{
if(temp->next->left)
return temp->next->left;
if(temp->next->right)
return temp->next->right;
temp = temp->next;
}
return NULL;
}
Node* connect(Node* root)
{
if(root==NULL)
return root;
Node* temp = NULL;
if(root->left)
{
if(root->right)
root->left->next = root->right;
else
root->left->next = getNext(root);
}
if(root->right)
root->right->next = getNext(root);
//先右后左,从后向前连接
connect(root->right);
connect(root->left);
return root;
}