Skip to content

Commit 33c4c5a

Browse files
Merge pull request #291 from Adi-3108/union
Add Union of Two Linked Lists implementation in CPP
2 parents 542184b + 6d9278e commit 33c4c5a

1 file changed

Lines changed: 160 additions & 0 deletions

File tree

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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

Comments
 (0)