Generating Random Unweighted Binary Tree:
- Since this is a tree, the test data generation plan is such that no cycle gets formed.
- The number of edges is one less than the number of vertices.
- For each RUN, first print the count of nodes say, N and the next N – 1 lines are of the form (a, b) where a is the parent of b.
- Each node contains at most 2 children.
Approach: The problem can be solved using Queue. The idea is to traverse the tree using BFS. Follow the steps below to solve the problem:
- Initialize a map, say mp to check if a node is already included in the tree or not.
- Initialize a queue to store the nodes at each level of the tree.
- Consider 1 as root node and insert it into the queue.
- Iterate over the queue while the total count of nodes in the tree not equal to N. In every iteration insert distinct nodes of each level of the tree into the queue using rand() function and the map, also insert the node and the parent of the node into an array
- Finally, print the value of N and the array.
CPP
// C++ Program to generate test cases for // an unweighted tree #include <bits/stdc++.h> using namespace std;
// Function to generate the binary tree using BFS vector<pair< int , int > > generateBinaryTree( int n)
{ // Stores number of children
// a node can have
vector< int > options = { 0, 1, 2 };
// Check if a node is already
// included in the tree or not
map< int , int > mp;
// Stores node of tree at
// each level of the tree
queue< int > q;
// Insert root node
q.push(1);
// Stores the generated tree
vector<pair< int , int > > v;
// Store count of nodes
// already included
int count = 1;
// Marking the inclusion
// of node 1
mp[1] = 1;
// Traverse tree using BFS
while (!q.empty() or count < n) {
// Stores from element
// of queue
int front;
if (!q.empty()) {
// Update front
front = q.front();
// Pop front element
// of queue
q.pop();
}
// Find count of child nodes
// of current node
int numberOfChilds
= options[ rand () % (options.size())];
// If all the nodes are
// already included
if (count >= n)
continue ;
// Connect child node to
// the parent node
while (numberOfChilds--) {
// Stores value in node which
// is not already included
int child = rand () % n + 1;
// Find the child until found a node
// that is not yet included
while (mp[child]) {
child++;
if (child > n) {
child = 1;
}
}
// Update count
count++;
// Mark the included node
mp[child] = 1;
// Insert it to the generated tree
// as {parent, child}
v.push_back({ front, child });
// Push the child into the queue
q.push(child);
// If all the nodes are included
// break
if (count == n)
break ;
}
}
// Shuffle the v vector randomly
random_shuffle(v.begin(), v.end());
return v;
} // Function to print the generated tree void printTree( int n, vector<pair< int , int > > v)
{ int s = v.size();
// Number of nodes
cout << n << "\n" ;
// Print n-1 edges as {parent, child}
for ( int i = 0; i < v.size(); i++) {
cout << v[i].first << " " << v[i].second << "\n" ;
}
} // Driver Code int main()
{ // Random seeding
srand ( time (NULL));
// Number of node between 3 to 8
// this range can be easily changed
int n = rand () % 6 + 3;
// Function Call
vector<pair< int , int > > v
= generateBinaryTree(n);
// Print the generated tree
printTree(n, v);
} |
Java
// Java Program for the above approach import java.util.*;
public class Main {
static List<Pair<Integer, Integer>> GenerateBinaryTree( int n) {
Random rand = new Random();
List<Integer> options = Arrays.asList( 0 , 1 , 2 );
Map<Integer, Integer> mp = new HashMap<>();
Queue<Integer> q = new LinkedList<>();
List<Pair<Integer, Integer>> v = new ArrayList<>();
int count = 1 ;
q.offer( 1 );
mp.put( 1 , 1 );
while (!q.isEmpty() || count < n) {
int front = 0 ;
if (!q.isEmpty()) {
front = q.poll();
}
int numberOfChilds = options.get(rand.nextInt(options.size()));
if (count >= n)
continue ;
while (numberOfChilds-- > 0 ) {
int child = rand.nextInt(n) + 1 ;
while (mp.containsKey(child)) {
child++;
if (child > n) {
child = 1 ;
}
}
count++;
mp.put(child, 1 );
v.add( new Pair<>(front, child));
q.offer(child);
if (count == n)
break ;
}
}
Collections.shuffle(v);
return v;
}
static void PrintTree( int n, List<Pair<Integer, Integer>> v) {
System.out.println(n);
for (Pair<Integer, Integer> edge : v) {
System.out.println(edge.getKey() + " " + edge.getValue());
}
}
public static void main(String[] args) {
Random rand = new Random();
int n = rand.nextInt( 7 ) + 3 ;
List<Pair<Integer, Integer>> v = GenerateBinaryTree(n);
PrintTree(n, v);
}
static class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
public static class Extensions {
public static <T> void shuffle(List<T> list) {
Random rand = new Random();
for ( int i = list.size() - 1 ; i > 0 ; i--) {
int j = rand.nextInt(i + 1 );
T temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
} // This code is contributed by Prince Kumar |
Python3
#Python code for the above approach import random
# Function to generate the binary tree using BFS def generateBinaryTree(n):
# Stores number of children
# a node can have
options = [ 0 , 1 , 2 ]
# Check if a node is already
# included in the tree or not
mp = {}
# Stores node of tree at
# each level of the tree
q = []
# Insert root node
q.append( 1 )
# Stores the generated tree
v = []
# Store count of nodes
# already included
count = 1
# Marking the inclusion
# of node 1
mp[ 1 ] = 1
# Traverse tree using BFS
while q or count < n:
# Stores from element
# of queue
front = 0
if q:
# Update front
front = q[ 0 ]
# Pop front element
# of queue
q.pop( 0 )
# Find count of child nodes
# of current node
numberOfChilds = options[random.randint( 0 , len (options) - 1 )]
# If all the nodes are
# already included
if count > = n:
continue
# Connect child node to
# the parent node
while numberOfChilds:
# Stores value in node which
# is not already included
child = random.randint( 1 , n)
# Find the child until found a node
# that is not yet included
while child in mp:
child + = 1
if child > n:
child = 1
# Update count
count + = 1
# Mark the included node
mp[child] = 1
# Insert it to the generated tree
# as {parent, child}
v.append((front, child))
# Push the child into the queue
q.append(child)
# If all the nodes are included
# break
if count = = n:
break
numberOfChilds - = 1
# Shuffle the v list randomly
random.shuffle(v)
return v
# Function to print the generated tree def printTree(n, v):
# Number of nodes
print (n)
# Print n-1 edges as {parent, child}
for i in range ( len (v)):
print (v[i][ 0 ], v[i][ 1 ])
# Driver Code def main():
# Random seeding
random.seed()
# Number of node between 3 to 8
# this range can be easily changed
n = random.randint( 3 , 8 )
# Function Call
v = generateBinaryTree(n)
# Print the generated tree
printTree(n, v)
main() # This code is contributed by Potta Lokesh |
C#
// C# program for the above approach using System;
using System.Collections.Generic;
public class Program
{ static List<( int , int )> GenerateBinaryTree( int n)
{
Random rand = new Random();
var options = new List< int > { 0, 1, 2 };
var mp = new Dictionary< int , int >();
var q = new Queue< int >();
var v = new List<( int , int )>();
int count = 1;
q.Enqueue(1);
mp[1] = 1;
while (q.Count > 0 || count < n)
{
int front = 0;
if (q.Count > 0)
{
front = q.Dequeue();
}
int numberOfChilds = options[rand.Next(options.Count)];
if (count >= n)
continue ;
while (numberOfChilds-- > 0)
{
int child = rand.Next(1, n + 1);
while (mp.ContainsKey(child))
{
child++;
if (child > n)
{
child = 1;
}
}
count++;
mp[child] = 1;
v.Add((front, child));
q.Enqueue(child);
if (count == n)
break ;
}
}
v.Shuffle();
return v;
}
static void PrintTree( int n, List<( int , int )> v)
{
Console.WriteLine(n);
foreach ( var edge in v)
{
Console.WriteLine($ "{edge.Item1} {edge.Item2}" );
}
}
public static void Main()
{
Random rand = new Random();
int n = rand.Next(3, 9);
var v = GenerateBinaryTree(n);
PrintTree(n, v);
}
} public static class Extensions
{ public static void Shuffle<T>( this IList<T> list)
{
Random rand = new Random();
for ( int i = list.Count - 1; i > 0; i--)
{
int j = rand.Next(i + 1);
T temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
} // This code is contribute by princekumaras |
Javascript
// Function to generate the binary tree using BFS function generateBinaryTree(n) {
// Stores number of children
// a node can have
const options = [0, 1, 2];
// Check if a node is already
// included in the tree or not
const mp = {};
// Stores node of tree at
// each level of the tree
const q = [];
// Insert root node
q.push(1);
// Stores the generated tree
const v = [];
// Store count of nodes
// already included
let count = 1;
// Marking the inclusion
// of node 1
mp[1] = 1;
// Traverse tree using BFS
while (q.length || count < n) {
// Stores from element
// of queue
let front = 0;
if (q.length) {
// Update front
front = q[0];
// Pop front element
// of queue
q.shift();
}
// Find count of child nodes
// of current node
let numberOfChilds = options[(Math.floor(Math.random() * options.length))];
// If all the nodes are
// already included
if (count >= n) {
continue ;
}
// Connect child node to
// the parent node
while (numberOfChilds) {
// Stores value in node which
// is not already included
let child = Math.floor(Math.random() * n) + 1;
// Find the child until found a node
// that is not yet included
while (mp[child]) {
child += 1;
if (child > n) {
child = 1;
}
}
// Update count
count += 1;
// Mark the included node
mp[child] = 1;
// Insert it to the generated tree
// as {parent, child}
v.push([front, child]);
// Push the child into the queue
q.push(child);
// If all the nodes are included
// break
if (count === n) {
break ;
}
numberOfChilds = numberOfChilds-1;
}
}
// Shuffle the v list randomly
shuffleArray(v);
return v;
} // Function to print the generated tree function printTree(n, v) {
// Number of nodes
console.log(n);
// Print n-1 edges as {parent, child}
for (let i = 0; i < v.length; i++) {
console.log(v[i][0], v[i][1]);
}
} // Helper function to shuffle array function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
} // Driver Code function main() {
// Random seeding
Math.random();
// Number of node between 3 to 8
// this range can be easily changed
const n = Math.floor(Math.random() * (8 - 3 + 1)) + 3;
// Function Call
const v = generateBinaryTree(n);
// Print the generated tree
printTree(n, v);
} main(); |
Output:
5 5 4 1 2 1 3 3 5
Time Complexity : O(N log N)
Auxiliary Space : O(N)