填充每个节点的下一个右侧节点指针 II

题目:

给定一个二叉树

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值