Open In App

Test Case Generation | Set 6 (Random Unweighted Binary Tree)

Improve
Improve
Like Article
Like
Save
Share
Report

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)



Last Updated : 17 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads