连接同一级别的节点(级别顺序遍历)
编写一个函数,将二叉树中同一级别的所有相邻节点连接起来。
例子:
Input Tree
A
/ \
B C
/ \ \
D E F
Output Tree
A--->NULL
/ \
B-->C-->NULL
/ \ \
D-->E-->F-->NULL
我们已经讨论过 O(n^2) 时间和在与 morris 遍历相同级别的 Connect 节点中的 O 方法,在最坏的情况下可能是 O(n) 并且调用它来设置右指针可能会导致 O(n^2) 时间复杂度.
在这篇文章中,我们讨论了带有 NULL 标记的级别顺序遍历,这是在树中标记级别所需的。
C++
// Connect nodes at same level using level order
// traversal.
#include
using namespace std;
struct Node {
int data;
struct Node* left, *right, *nextRight;
};
// Sets nextRight of all nodes of a tree
void connect(struct Node* root)
{
queue q;
q.push(root);
// null marker to represent end of current level
q.push(NULL);
// Do Level order of tree using NULL markers
while (!q.empty()) {
Node *p = q.front();
q.pop();
if (p != NULL) {
// next element in queue represents next
// node at current Level
p->nextRight = q.front();
// push left and right children of current
// node
if (p->left)
q.push(p->left);
if (p->right)
q.push(p->right);
}
// if queue is not empty, push NULL to mark
// nodes at this level are visited
else if (!q.empty())
q.push(NULL);
}
}
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct Node* newnode(int data)
{
struct Node* node = (struct Node*)
malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = node->nextRight = NULL;
return (node);
}
/* Driver program to test above functions*/
int main()
{
/* Constructed binary tree is
10
/ \
8 2
/ \
3 90
*/
struct Node* root = newnode(10);
root->left = newnode(8);
root->right = newnode(2);
root->left->left = newnode(3);
root->right->right = newnode(90);
// Populates nextRight pointer in all nodes
connect(root);
// Let us check the values of nextRight pointers
printf("Following are populated nextRight pointers in \n"
"the tree (-1 is printed if there is no nextRight) \n");
printf("nextRight of %d is %d \n", root->data,
root->nextRight ? root->nextRight->data : -1);
printf("nextRight of %d is %d \n", root->left->data,
root->left->nextRight ? root->left->nextRight->data : -1);
printf("nextRight of %d is %d \n", root->right->data,
root->right->nextRight ? root->right->nextRight->data : -1);
printf("nextRight of %d is %d \n", root->left->left->data,
root->left->left->nextRight ? root->left->left->nextRight->data : -1);
printf("nextRight of %d is %d \n", root->right->right->data,
root->right->right->nextRight ? root->right->right->nextRight->data : -1);
return 0;
}
Java
// Connect nodes at same level using level order
// traversal.
import java.util.LinkedList;
import java.util.Queue;
public class Connect_node_same_level {
// Node class
static class Node {
int data;
Node left, right, nextRight;
Node(int data){
this.data = data;
left = null;
right = null;
nextRight = null;
}
};
// Sets nextRight of all nodes of a tree
static void connect(Node root)
{
Queue q = new LinkedList();
q.add(root);
// null marker to represent end of current level
q.add(null);
// Do Level order of tree using NULL markers
while (!q.isEmpty()) {
Node p = q.peek();
q.remove();
if (p != null) {
// next element in queue represents next
// node at current Level
p.nextRight = q.peek();
// push left and right children of current
// node
if (p.left != null)
q.add(p.left);
if (p.right != null)
q.add(p.right);
}
// if queue is not empty, push NULL to mark
// nodes at this level are visited
else if (!q.isEmpty())
q.add(null);
}
}
/* Driver program to test above functions*/
public static void main(String args[])
{
/* Constructed binary tree is
10
/ \
8 2
/ \
3 90
*/
Node root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.right.right = new Node(90);
// Populates nextRight pointer in all nodes
connect(root);
// Let us check the values of nextRight pointers
System.out.println("Following are populated nextRight pointers in \n" +
"the tree (-1 is printed if there is no nextRight)");
System.out.println("nextRight of "+ root.data +" is "+
((root.nextRight != null) ? root.nextRight.data : -1));
System.out.println("nextRight of "+ root.left.data+" is "+
((root.left.nextRight != null) ? root.left.nextRight.data : -1));
System.out.println("nextRight of "+ root.right.data+" is "+
((root.right.nextRight != null) ? root.right.nextRight.data : -1));
System.out.println("nextRight of "+ root.left.left.data+" is "+
((root.left.left.nextRight != null) ? root.left.left.nextRight.data : -1));
System.out.println("nextRight of "+ root.right.right.data+" is "+
((root.right.right.nextRight != null) ? root.right.right.nextRight.data : -1));
}
}
// This code is contributed by Sumit Ghosh
Python3
#! /usr/bin/env python3
# connect nodes at same level using level order traversal
import sys
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.nextRight = None
def __str__(self):
return '{}'.format(self.data)
def printLevelByLevel(root):
# print level by level
if root:
node = root
while node:
print('{}'.format(node.data), end=' ')
node = node.nextRight
print()
if root.left:
printLevelByLevel(root.left)
else:
printLevelByLevel(root.right)
def inorder(root):
if root:
inorder(root.left)
print(root.data, end=' ')
inorder(root.right)
def connect(root):
# set nextRight of all nodes of a tree
queue = []
queue.append(root)
# null marker to represent end of current level
queue.append(None)
# do level order of tree using None markers
while queue:
p = queue.pop(0)
if p:
# next element in queue represents
# next node at current level
p.nextRight = queue[0]
# pus left and right children of current node
if p.left:
queue.append(p.left)
if p.right:
queue.append(p.right)
else if queue:
queue.append(None)
def main():
"""Driver program to test above functions.
Constructed binary tree is
10
/ \
8 2
/ \
3 90
"""
root = Node(10)
root.left = Node(8)
root.right = Node(2)
root.left.left = Node(3)
root.right.right = Node(90)
# Populates nextRight pointer in all nodes
connect(root)
# Let us check the values of nextRight pointers
print("Following are populated nextRight pointers in \n"
"the tree (-1 is printed if there is no nextRight) \n")
if(root.nextRight != None):
print("nextRight of %d is %d \n" %(root.data,root.nextRight.data))
else:
print("nextRight of %d is %d \n" %(root.data,-1))
if(root.left.nextRight != None):
print("nextRight of %d is %d \n" %(root.left.data,root.left.nextRight.data))
else:
print("nextRight of %d is %d \n" %(root.left.data,-1))
if(root.right.nextRight != None):
print("nextRight of %d is %d \n" %(root.right.data,root.right.nextRight.data))
else:
print("nextRight of %d is %d \n" %(root.right.data,-1))
if(root.left.left.nextRight != None):
print("nextRight of %d is %d \n" %(root.left.left.data,root.left.left.nextRight.data))
else:
print("nextRight of %d is %d \n" %(root.left.left.data,-1))
if(root.right.right.nextRight != None):
print("nextRight of %d is %d \n" %(root.right.right.data,root.right.right.nextRight.data))
else:
print("nextRight of %d is %d \n" %(root.right.right.data,-1))
print()
if __name__ == "__main__":
main()
# This code is contributed by Ram Basnet
C#
// Connect nodes at same level using level order
// traversal.
using System;
using System.Collections.Generic;
public class Connect_node_same_level
{
// Node class
class Node
{
public int data;
public Node left, right, nextRight;
public Node(int data)
{
this.data = data;
left = null;
right = null;
nextRight = null;
}
};
// Sets nextRight of all nodes of a tree
static void connect(Node root)
{
Queue q = new Queue();
q.Enqueue(root);
// null marker to represent end of current level
q.Enqueue(null);
// Do Level order of tree using NULL markers
while (q.Count!=0)
{
Node p = q.Peek();
q.Dequeue();
if (p != null)
{
// next element in queue represents next
// node at current Level
p.nextRight = q.Peek();
// push left and right children of current
// node
if (p.left != null)
q.Enqueue(p.left);
if (p.right != null)
q.Enqueue(p.right);
}
// if queue is not empty, push NULL to mark
// nodes at this level are visited
else if (q.Count!=0)
q.Enqueue(null);
}
}
/* Driver code*/
public static void Main()
{
/* Constructed binary tree is
10
/ \
8 2
/ \
3 90
*/
Node root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.right.right = new Node(90);
// Populates nextRight pointer in all nodes
connect(root);
// Let us check the values of nextRight pointers
Console.WriteLine("Following are populated nextRight pointers in \n" +
"the tree (-1 is printed if there is no nextRight)");
Console.WriteLine("nextRight of "+ root.data +" is "+
((root.nextRight != null) ? root.nextRight.data : -1));
Console.WriteLine("nextRight of "+ root.left.data+" is "+
((root.left.nextRight != null) ? root.left.nextRight.data : -1));
Console.WriteLine("nextRight of "+ root.right.data+" is "+
((root.right.nextRight != null) ? root.right.nextRight.data : -1));
Console.WriteLine("nextRight of "+ root.left.left.data+" is "+
((root.left.left.nextRight != null) ? root.left.left.nextRight.data : -1));
Console.WriteLine("nextRight of "+ root.right.right.data+" is "+
((root.right.right.nextRight != null) ? root.right.right.nextRight.data : -1));
}
}
/* This code is contributed by Rajput-Ji*/
Javascript
输出:
Following are populated nextRight pointers in
the tree (-1 is printed if there is no nextRight)
nextRight of 10 is -1
nextRight of 8 is 2
nextRight of 2 is -1
nextRight of 3 is 90
nextRight of 90 is -1
时间复杂度: O(n),其中 n 是节点数
替代实施:
我们也可以按照打印级顺序遍历中讨论的实现逐行 | Set 1. 我们通过跟踪以前访问过的同级节点来保持连接同级节点。
实施:https://ide.geeksforgeeks.org/gV1Oc2
感谢 Akilan Sengottaiyan 提出了这个替代实现的建议。