# C++ Program For Selecting A Random Node From A Singly Linked List

Given a singly linked list, select a random node from the linked list (the probability of picking a node should be 1/N if there are N nodes in the list). You are given a random number generator.
Below is a Simple Solution:

1. Count the number of nodes by traversing the list.
2. Traverse the list again and select every node with probability 1/N. The selection can be done by generating a random number from 0 to N-i for i’th node, and selecting the i’th node only if the generated number is equal to 0 (or any other fixed number from 0 to N-i).

We get uniform probabilities with the above schemes.

```i = 1, probability of selecting first node = 1/N
i = 2, probability of selecting second node =
[probability that first node is not selected] *
[probability that second node is selected]
= ((N-1)/N)* 1/(N-1)
= 1/N  ```

Similarly, probabilities of other selecting other nodes is 1/N
The above solution requires two traversals of linked list.

How to select a random node with only one traversal allowed?
The idea is to use Reservoir Sampling. Following are the steps. This is a simpler version of Reservoir Sampling as we need to select only one key instead of k keys.

```(1) Initialize result as first node
(2) Initialize n = 2
(3) Now one by one consider all nodes from 2nd node onward.
(a) Generate a random number from 0 to n-1.
Let the generated random number is j.
(b) If j is equal to 0 (we could choose other fixed numbers
between 0 to n-1), then replace result with the current node.
(c) n = n+1
(d) current = current->next```

Below is the implementation of above algorithm.

## C++

 `/* C++ program to randomly select  ``   ``a node from a singly linked list */``#include ``#include ``#include ``#include ``using` `namespace` `std; `` ` `// Link list node  ``class` `Node ``{ ``    ``public``: ``    ``int` `key; ``    ``Node* next; ``    ``void` `printRandom(Node*); ``    ``void` `push(Node**, ``int``); ``     ` `}; `` ` `// A reservoir sampling-based function to  ``// print a random node from a linked list ``void` `Node::printRandom(Node *head) ``{ ``    ``// If list is empty ``    ``if` `(head == NULL) ``    ``return``; `` ` `    ``// Use a different seed value so that  ``    ``// we don't get same result each time  ``    ``// we run this program ``    ``srand``(``time``(NULL)); `` ` `    ``// Initialize result as first node ``    ``int` `result = head->key; `` ` `    ``// Iterate from the (k+1)th element  ``    ``// to nth element ``    ``Node *current = head; ``    ``int` `n; ``    ``for` `(n = 2; current != NULL; n++) ``    ``{ ``        ``// Change result with  ``        ``// probability 1/n ``        ``if` `(``rand``() % n == 0) ``        ``result = current->key; `` ` `        ``// Move to next node ``        ``current = current->next; ``    ``} `` ` `    ``cout << ``"Randomly selected key is "` `<<  ``             ``result; ``} `` ` `/* A utility function to create  ``   ``a new node */``Node* newNode(``int` `new_key) ``{ ``    ``// Allocate node  ``    ``Node* new_node =  ``          ``(Node*) ``malloc``(``sizeof``( Node)); `` ` `    ``/// Put in the key  ``    ``new_node->key = new_key; ``    ``new_node->next = NULL; `` ` `    ``return` `new_node; ``} `` ` `/* A utility function to insert a  ``   ``node at the beginning of linked list */``void` `Node:: push(Node** head_ref,  ``                 ``int` `new_key) ``{ ``    ``// Allocate node  ``    ``Node* new_node = ``new` `Node; `` ` `    ``// Put in the key  ``    ``new_node->key = new_key; `` ` `    ``// Link the old list off the  ``    ``// new node  ``    ``new_node->next = (*head_ref); `` ` `    ``// Move the head to point to  ``    ``// the new node  ``    ``(*head_ref) = new_node; ``} `` ` `// Driver code ``int` `main() ``{ ``    ``Node n1; ``    ``Node *head = NULL; ``    ``n1.push(&head, 5); ``    ``n1.push(&head, 20); ``    ``n1.push(&head, 4); ``    ``n1.push(&head, 3); ``    ``n1.push(&head, 30); ``    ``n1.printRandom(head); ``    ``return` `0; ``} ``// This code is contributed by SoumikMondal `

Note that the above program is based on the outcome of a random function and may produce different output.

The algorithm implemented in the code is called “Reservoir Sampling”. It is a technique for selecting a random item from a large data stream with equal probability.

Here’s an algorithm to randomly select a node from a singly linked list in C++:

1.Calculate the length of the linked list, let’s call it n.
2.Generate a random number in the range [0, n-1]. This can be done using the rand() function in C++.
3.Start at the head of the linked list and traverse the linked list until the randomly generated index is reached.
4.Return the node at the randomly generated index.
Here’s some sample code to implement the algorithm in C++:

## C++

 `#include ``#include ``#include `` ` `struct` `Node { ``  ``int` `data; ``  ``Node* next; ``}; `` ` `int` `getLength(Node* head) { ``  ``int` `count = 0; ``  ``Node* current = head; ``  ``while` `(current != nullptr) { ``    ``count++; ``    ``current = current->next; ``  ``} ``  ``return` `count; ``} `` ` `Node* getRandomNode(Node* head) { ``  ``int` `length = getLength(head); ``  ``int` `randomIndex = ``rand``() % length; ``  ``Node* current = head; ``  ``for` `(``int` `i = 0; i < randomIndex; i++) { ``    ``current = current->next; ``  ``} ``  ``return` `current; ``} `` ` `int` `main() { ``  ``srand``(``time``(0)); `` ` `  ``Node* head = ``new` `Node{1, nullptr}; ``  ``head->next = ``new` `Node{2, nullptr}; ``  ``head->next->next = ``new` `Node{3, nullptr}; ``  ``head->next->next->next = ``new` `Node{4, nullptr}; `` ` `  ``Node* randomNode = getRandomNode(head); ``  ``std::cout << ``"Random node: "` `<< randomNode->data << std::endl; `` ` `  ``return` `0; ``} `

How does this work?
Let there be total N nodes in list. It is easier to understand from the last node.
The probability that the last node is result simply 1/N [For last or N’th node, we generate a random number between 0 to N-1 and make the last node as a result if the generated number is 0 (or any other fixed number]
The probability that second last node is result should also be 1/N.

```The probability that the second last node is result
= [Probability that the second last node replaces result] X
[Probability that the last node doesn't replace the result]
= [1 / (N-1)] * [(N-1)/N]
= 1/N```

Similarly, we can show probability for 3rd last node and other nodes. Please refer complete article on Select a Random Node from a Singly Linked List for more details!

Previous
Next