各ノードレベルのトラバーサルまたはトラバーサルポインターの次の右側のノードポインターを入力します

leetcodeの2つのサブジェクトアドレス:

完全な二分木バージョン
は、各ノードの次の右ノードポインタを埋めます

各ノードの次の右ノードポインタを埋めます||

ここに画像の説明を挿入
データの種類:

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

1.レベルトラバーサル

レベルトラバーサル(基本的に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;
	}
};

次に、既存の次のポインタを使用します

ツリー上のすべてのノードを処理する必要があるため、時間の複雑さを軽減することはできませんが、スペースの複雑さを軽減することはできます。

特定のレイヤーのノード間に次のポインターが確立されると、このレイヤーのノードが実際にリンクリストを形成することを見つけるのは難しくありません。したがって、最初に特定のレイヤーの次のポインターを確立してから、このレイヤーをトラバースする場合、キューを使用する必要はありません。

完璧な二分木のために:

ノードは完全である必要があり、親ノードに子ノードが1つしかない状況はありません。

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

不完全な二分木

親ノードに子ノードがないか、子ノードが1つしかない状況が発生します。

前のポインタと次のレイヤーの開始位置を記録する必要があります。

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