Оглавление
117. Заполняем указатель следующего правого узла каждого узла II — LeetCode
Учитывая двоичное дерево:
структура Node { int val; Узел *слева; Узел *справа; Узел *следующий; }Заполните каждый из его следующих указателей так, чтобы этот указатель указывал на следующий правый узел. Если следующий правый узел не найден, следующий указатель устанавливается на
NULL
.Изначально все указатели next установлены на
NULL
.Пример 1:
Ввод : root = [1,2,3,4,5,null,7] Вывод: [1,#,2,3,#,4,5,7,#] Объяснение: Данное двоичное дерево показано на рисунке. A ваша функция должна заполнить каждый из своих следующих указателей, чтобы указать на следующий правый узел, как показано на рисунке B. Сериализованный вывод имеет порядок обхода по уровням (соединен указателями следующего), где «#» указывает на конец каждого слоя.Пример 2:
Ввод: корень = [] Вывод: []намекать:
- Количество узлов в дереве находится
[0, 6000]
в пределах-100 <= Node.val <= 100
отвечать:
- Определен метод
connect()
, который принимаетNode
параметр типаroot
, представляющий корневой узел двоичного дерева. Если корневой узел пуст, вернитесь напрямую. Затем создайте очередьqueue
для обхода бинарного дерева по уровням.- Затем поставьте в очередь корневой узел.
- Войдите в цикл и продолжайте выполнение до тех пор, пока очередь не пуста. В каждом раунде цикла сначала получите количество узлов на текущем уровне
size
и инициализируйте предыдущий обработанный узелlast
и текущий узелnode
равными нулю.- Затем во внутреннем цикле узел извлекается с помощью операции удаления из очереди
node
. Если предыдущий узелlast
не пуст, наведите егоnext
указатель на текущий узелnode
, чтобы соединить соседние узлы.- В то же время, если левый дочерний узел текущего узла не пуст, его левый дочерний узел ставится в очередь; если правый дочерний узел текущего узла не пуст, его правый дочерний узел ставится в очередь.
- Наконец, обновите
last
текущий узелnode
для использования в следующем цикле.- Когда все узлы пройдены, вернитесь к корневому узлу
root
.- Основная идея этого кода — использовать очереди для обхода по уровням и соединять соседние узлы в процессе обхода. Таким образом, может быть достигнуто соединение узлов двоичного дерева «следующий правый узел».
Код:
/* // Definition for a Node. class Node { public int val; public Node left; public Node right; public Node next; public Node() {} public Node(int _val) { val = _val; } public Node(int _val, Node _left, Node _right, Node _next) { val = _val; left = _left; right = _right; next = _next; } }; */ class Solution { public Node connect(Node root) { if(root==null) return root; // 定义队列用于层序遍历 Queue<Node> queue=new LinkedList<>(); // 根节点进队 queue.offer(root); Node last;//上一个队首 Node node;//当前队首 int size=0; while(!queue.isEmpty()){//通过队列的size横向控制每层的遍历 size=queue.size(); last=null;//每一层开始的上一个节点为空 while(size>0){ // 获取队首(由于只能获取队首而不是前两个,所以我们用提前存储上一个节点与当前获取的队首链接) node=queue.poll();//获取当前节点 if(last!=null) last.next=node;//不为空说明他们是一层的,连接起来 if(node.left!=null) queue.offer(node.left);//子节点入队 if(node.right!=null) queue.offer(node.right); last=node; size--; } } return root; } }
результат операции: