填充每个节点的下一个右侧节点指针——层次遍历或遍历指针

leetcode两道题目地址:

完美二叉树版
填充每个节点的下一个右侧节点指针

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

在这里插入图片描述
数据类型:

class Node {
    
    
public:
    int val;
    Node* left;
    Node* right;
    Node* next;
    Node() : val(0), left(NULL), right(NULL), next(NULL) {
    
    }
    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {
    
    }
    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {
    
    }
};

一、层次遍历

使用层次遍历(实质为BFS),遍历每一层然后不断赋值,思路简单明了。
两道题都可以。

class Solution {
    
    
public:
	Node* connect(Node* root)
	{
    
    
		if (!root)
			return NULL;
		queue< Node*> q;
		q.push(root);
		while (!q.empty())
		{
    
    
			int n = q.size();
			Node* node = NULL;
			for (int i = 0; i < n; i++)
			{
    
    
				Node* f = q.front();
				q.pop();
				if (f->left!=NULL)
				{
    
    
					q.push(f->left);
				}
				if (f->right!=NULL)
				{
    
    
					q.push(f->right);
				}
				if (i != 0)
				{
    
    
					node->next = f;
				}
				node = f;

			}
		}
		return root;
	}
};

二、使用已有的next指针

因为必须处理树上的所有节点,所以无法降低时间复杂度,但是可以尝试降低空间复杂度。

不难发现:一旦在某层的节点之间建立了 next指针,那这层节点实际上形成了一个链表。因此,如果先去建立某一层的 next 指针,再去遍历这一层,就无需再使用队列了。

对于完美二叉树:

节点一定完整,不存在一个父节点只有一个子节点的情况。

class Solution {
    
    
public:
	Node* connect(Node* root) 
	{
    
    
		Node* head = root;
		if (!head)
			return NULL;
		while (head->left!=nullptr)
		{
    
    
			Node* center = head;
			while (center)
			{
    
    
				center->left->next = center->right;
				if (center->next)
					center->right->next = center->next->left;
				center = center->next;
			}
			head = head->left;
		}
		return root;
	}
};

非完美二叉树

会出现一个父节点没有子节点或者只有一个的情况。

就需要记录前一位指针,和下一层的起始位置。

class Solution {
    
    
public:
	void handle(Node*& last, Node*& p, Node*& nextStart) {
    
    
	//前一位指针,当前连接的指针p,下层的首部节点nextstart
		if (last) 
			last->next = p;
		if (!nextStart) //为空则等于p
			nextStart = p;
		last = p;
	}
	Node* connect(Node* root) 
	{
    
    
		if (!root) 
		{
    
    
			return nullptr;
		}
		Node* start = root;
		while (start) 
		{
    
    
			Node* last = nullptr, * nextStart = nullptr;
			for (Node* p = start; p != nullptr; p = p->next) 
			{
    
    //给下一层建立next指针
				if (p->left) 
					handle(last, p->left, nextStart); 
				if (p->right) 
					handle(last, p->right, nextStart);
			}
			//最后一个nextstart则为下一层开始的起始指针
			start = nextStart;
		}
		return root;
	}
};

猜你喜欢

转载自blog.csdn.net/weixin_45605341/article/details/109092139