1+ /*
2+ * Algorithm: Union of Two Linked Lists
3+ * Language: C++
4+ * Description:
5+ * Computes the union of two given singly linked lists. The union contains all
6+ * elements that are present in either list, with duplicates removed.
7+ * This implementation uses a Hash Set (unordered_set) for efficient duplicate
8+ * checking and insertion.
9+ * Time Complexity: O(N + M) // Where N and M are the lengths of the two lists
10+ * Space Complexity: O(N + M) // To store elements in the Hash Set
11+ * Author: Adi-3108
12+ */
13+
14+ #include < iostream>
15+ #include < unordered_set>
16+ #include < algorithm>
17+ #include < vector>
18+
19+ using namespace std ;
20+
21+
22+ struct Node {
23+ int data;
24+ Node* next;
25+ Node (int x) : data(x), next(NULL ) {}
26+ };
27+
28+ /* *
29+ * @brief Computes the union of two linked lists using a hash set.
30+ * * @param head1 Head of the first linked list.
31+ * @param head2 Head of the second linked list.
32+ * @return Node* Head of the new linked list representing the union.
33+ */
34+ Node* findUnion (Node* head1, Node* head2) {
35+ // Hash set to store all unique elements encountered.
36+ unordered_set<int > unique_elements;
37+
38+ // --- Phase 1: Traverse List 1 and add elements to the set ---
39+ Node* current = head1;
40+ while (current != NULL ) {
41+ unique_elements.insert (current->data );
42+ current = current->next ;
43+ }
44+
45+ // --- Phase 2: Traverse List 2 and add elements to the set ---
46+ // The set automatically handles duplicates, so this phase guarantees all
47+ // unique elements from both lists are now present.
48+ current = head2;
49+ while (current != NULL ) {
50+ unique_elements.insert (current->data );
51+ current = current->next ;
52+ }
53+
54+ // --- Phase 3: Construct the result linked list from the set ---
55+ Node* result_head = NULL ;
56+ Node* result_tail = NULL ;
57+
58+ // Note: Iterating a hash set does not preserve the original order of insertion,
59+ // which is generally acceptable for a set operation like Union.
60+ for (int val : unique_elements) {
61+ Node* new_node = new Node (val);
62+
63+ if (result_head == NULL ) {
64+ result_head = new_node;
65+ result_tail = new_node;
66+ } else {
67+ result_tail->next = new_node;
68+ result_tail = new_node;
69+ }
70+ }
71+
72+ return result_head;
73+ }
74+
75+
76+
77+ // Function to print the Linked List
78+ void printList (Node* head) {
79+ Node* current = head;
80+ cout << " [" ;
81+ while (current != NULL ) {
82+ cout << current->data ;
83+ if (current->next != NULL ) {
84+ cout << " , " ;
85+ }
86+ current = current->next ;
87+ }
88+ cout << " ]" ;
89+ }
90+
91+ // Function to Clean up the memory used by linked list
92+ void deleteList (Node* head) {
93+ Node* current = head;
94+ Node* next;
95+ while (current != NULL ) {
96+ next = current->next ;
97+ delete current;
98+ current = next;
99+ }
100+ }
101+ // Test Function
102+ void testUnionOfLists () {
103+ cout << " Testing Union of Two Linked Lists " << endl;
104+
105+ // List 1: 10 -> 20 -> 5 -> 15
106+ Node* head1 = new Node (10 );
107+ head1->next = new Node (20 );
108+ head1->next ->next = new Node (5 );
109+ head1->next ->next ->next = new Node (15 );
110+
111+ // List 2: 20 -> 25 -> 10 -> 30
112+ // Note: 20 and 10 are duplicates
113+ Node* head2 = new Node (20 );
114+ head2->next = new Node (25 );
115+ head2->next ->next = new Node (10 );
116+ head2->next ->next ->next = new Node (30 );
117+
118+ cout << " List 1: " ;
119+ printList (head1);
120+ cout << endl;
121+
122+ cout << " List 2: " ;
123+ printList (head2);
124+ cout << endl;
125+
126+ // Expected unique elements: {10, 20, 5, 15, 25, 30}. Order may vary.
127+ // Total unique count: 6
128+ Node* union_list = findUnion (head1, head2);
129+
130+ cout << " Union List (Order may vary): " ;
131+ printList (union_list);
132+ cout << endl;
133+
134+ // Simple check on the size of the union (to ensure correctness)
135+ unordered_set<int > expected_elements = {10 , 20 , 5 , 15 , 25 , 30 };
136+ int actual_count = 0 ;
137+ Node* current = union_list;
138+ while (current != NULL ) {
139+ actual_count++;
140+ current = current->next ;
141+ }
142+ // Printin Expected elements.size() for verification purpose
143+ cout << " Expected unique element count: " << expected_elements.size () << endl;
144+ cout << " Actual unique element count: " << actual_count << endl;
145+
146+ // Check if the counts match
147+ cout << " Count Check: "
148+ << (actual_count == expected_elements.size () ? " PASS" : " FAIL" )
149+ << endl;
150+
151+
152+ deleteList (head1);
153+ deleteList (head2);
154+ deleteList (union_list);
155+ }
156+
157+ int main () {
158+ testUnionOfLists ();
159+ return 0 ;
160+ }
0 commit comments