Test Case Generation | Set 6 (Random Unweighted Binary Tree)
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)
Please Login to comment...