Beginning Of The Loop
#include <bits/stdc++.h> // Common includesusing namespace std; // Standard namespace
// Node Class: Defines structure of a linked list nodeclass Node {public: int data; // Data storage Node* next; // Pointer to next node
// Node Constructor Node(int data) { this->data = data; this->next = NULL; // Initialize next as NULL }};
// printList: Prints all elements in the listvoid printList(Node* head) { if(head == NULL) { cout << "List is Empty!" << endl; return; }
cout << "Singly List : "; while(head != NULL) { cout << head->data << " "; // Print data head = head->next; // Move to next node } cout << endl;}
// insertAtHead: Adds node to the beginningvoid insertAtHead(Node* &head, int data) { Node *temp = new Node(data); // Create new node temp->next = head; // New node points to old head head = temp; // Head updates to new node}
// insertAtTail: Adds node to the endvoid insertAtTail(Node* &tail, int data) { Node *temp = new Node(data); // Create new node tail->next = temp; // Old tail points to new node tail = temp; // Tail updates to new node}
// insertAtMiddle: Inserts node at a specific positionvoid insertAtMiddle(Node* &head, Node* &tail, int data, int pos) { if(pos == 1) { // Special case: insert at head insertAtHead(head, data); return; }
Node *temp = head; // Traverse pointer while(temp != NULL && pos > 2) { // Find node BEFORE insertion point temp = temp->next; pos--; }
if(temp==NULL || pos<=0) { // Invalid position check cout << "Invalid Position!" << endl; return; }
Node *insertNode = new Node(data); // Create node to insert insertNode->next = temp->next; // New node points to temp's next temp->next = insertNode; // Temp points to new node
if(insertNode->next == NULL) { // Update tail if inserted at end tail = insertNode; }}
// deletePosition: Deletes node at a specific positionvoid deletePosition(Node* &head, int pos) { Node *temp = head; // Pointer for deletion/traversal if(pos == 1) { // Special case: delete head head = head->next; delete temp; // Free memory return; }
while(temp!=NULL && pos > 2) { // Find node BEFORE deletion point temp = temp->next; pos--; }
if(temp==NULL || temp->next==NULL || pos<=0) { // Invalid position check cout << "Invalid Position!" << endl; return; }
Node* target = temp->next; // Node to be deleted temp->next = target->next; // Bypass target node delete target; // Free memory}
// deleteValue: Deletes first occurrence of a specific valuevoid deleteValue(Node* &head, int val) { Node* temp = head->next; // Current pointer Node* prev = head; // Previous pointer
if(head->data == val) { // Special case: delete head by value head = head->next; delete prev; // Free old head return; }
// Traverse to find the value while(temp!=NULL) { if(temp->data == val) { val = INT_MIN; // Sentinel to mark value found break; } prev = temp; // Move prev temp = temp->next; // Move temp }
if(prev->next==NULL || val!=INT_MIN) { // Value not found cout << "Value Not Found!" << endl; return; }
prev->next = temp->next; // Bypass target node delete temp; // Free memory}
// beginningPoint: Finds the starting node of a loop in a linked list (assumes a loop exists)Node* beginningPoint(Node* head) { if(head == NULL) { // Empty list, no loop, no beginning point return head; }
Node* slow = head; // Slow pointer (1 step) Node* fast = head; // Fast pointer (2 steps)
// STEP 1: Find Intersection Node (where slow and fast meet) // This is the same logic as Floyd's cycle detection while(slow != NULL && fast != NULL) { fast = fast->next; // Fast moves 1 step slow = slow->next; // Slow moves 1 step
if(fast != NULL) { // Ensure fast is not NULL before moving it again fast = fast->next; // Fast moves another step }
if(slow == fast) { // Pointers meet, loop detected, break break; } }
// If loop was not found (e.g., list was not guaranteed to have a loop) // This function assumes a loop exists, so this case shouldn't be hit if used correctly. if (slow == NULL || fast == NULL) { return NULL; // No loop found, or list ended }
// STEP 2: Appoint slow to head // Reset slow pointer to the head of the list slow = head;
// STEP 3: Again Start Traversing Pointers // Move both slow and fast one step at a time. // They will meet at the beginning of the loop. while(slow != fast) { slow = slow->next; fast = fast->next; }
// STEP 4: Got the Beginning Point // Both pointers are now at the start of the loop return slow;}
// main: Program entry point, demonstrates operationsint main() { Node *head = new Node(1); // Create initial node Node *tail = head; // Tail points to head initially
// Build list: 1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 64 -> 128 for(int i=1; i<=7; i++) { insertAtTail(tail, pow(2,i)); } printList(head); // Print original list
// Create a cycle for testing: 128 points to 8 (head->next->next->next) // List: 1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 64 -> 128 -> (points to 8) tail->next = head->next->next->next;
// Find the beginning point of the loop Node* loopStartNode = beginningPoint(head);
// Print the data of the beginning point if (loopStartNode != NULL) { cout << "Beginning point of the loop : " << loopStartNode->data << endl; } else { cout << "No loop found or list is empty." << endl; }
return 0; // Indicate success}#include <bits/stdc++.h> // Common includesusing namespace std; // Standard namespace
// Node Class: Defines structure of a linked list nodeclass Node {public: int data; // Data storage Node* next; // Pointer to next node
// Node Constructor Node(int data) { this->data = data; this->next = NULL; // Initialize next as NULL }};
// printList: Prints all elements in the listvoid printList(Node* head) { if(head == NULL) { cout << "List is Empty!" << endl; return; }
cout << "Singly List : "; while(head != NULL) { cout << head->data << " "; // Print data head = head->next; // Move to next node } cout << endl;}
// insertAtHead: Adds node to the beginningvoid insertAtHead(Node* &head, int data) { Node *temp = new Node(data); // Create new node temp->next = head; // New node points to old head head = temp; // Head updates to new node}
// insertAtTail: Adds node to the endvoid insertAtTail(Node* &tail, int data) { Node *temp = new Node(data); // Create new node tail->next = temp; // Old tail points to new node tail = temp; // Tail updates to new node}
// insertAtMiddle: Inserts node at a specific positionvoid insertAtMiddle(Node* &head, Node* &tail, int data, int pos) { if(pos == 1) { // Special case: insert at head insertAtHead(head, data); return; }
Node *temp = head; // Traverse pointer while(temp != NULL && pos > 2) { // Find node BEFORE insertion point temp = temp->next; pos--; }
if(temp==NULL || pos<=0) { // Invalid position check cout << "Invalid Position!" << endl; return; }
Node *insertNode = new Node(data); // Create node to insert insertNode->next = temp->next; // New node points to temp's next temp->next = insertNode; // Temp points to new node
if(insertNode->next == NULL) { // Update tail if inserted at end tail = insertNode; }}
// deletePosition: Deletes node at a specific positionvoid deletePosition(Node* &head, int pos) { Node *temp = head; // Pointer for deletion/traversal if(pos == 1) { // Special case: delete head head = head->next; delete temp; // Free memory return; }
while(temp!=NULL && pos > 2) { // Find node BEFORE deletion point temp = temp->next; pos--; }
if(temp==NULL || temp->next==NULL || pos<=0) { // Invalid position check cout << "Invalid Position!" << endl; return; }
Node* target = temp->next; // Node to be deleted temp->next = target->next; // Bypass target node delete target; // Free memory}
// deleteValue: Deletes first occurrence of a specific valuevoid deleteValue(Node* &head, int val) { Node* temp = head->next; // Current pointer Node* prev = head; // Previous pointer
if(head->data == val) { // Special case: delete head by value head = head->next; delete prev; // Free old head return; }
// Traverse to find the value while(temp!=NULL) { if(temp->data == val) { val = INT_MIN; // Sentinel to mark value found break; } prev = temp; // Move prev temp = temp->next; // Move temp }
if(prev->next==NULL || val!=INT_MIN) { // Value not found cout << "Value Not Found!" << endl; return; }
prev->next = temp->next; // Bypass target node delete temp; // Free memory}
// beginningPoint: Finds the starting node of a loop in a linked list (assumes a loop exists)Node* beginningPoint(Node* head) { if(head == NULL) { // Empty list, no loop, no beginning point return head; }
Node* slow = head; // Slow pointer (1 step) Node* fast = head; // Fast pointer (2 steps)
// STEP 1: Find Intersection Node (where slow and fast meet) // This is the same logic as Floyd's cycle detection while(slow != NULL && fast != NULL) { fast = fast->next; // Fast moves 1 step slow = slow->next; // Slow moves 1 step
if(fast != NULL) { // Ensure fast is not NULL before moving it again fast = fast->next; // Fast moves another step }
if(slow == fast) { // Pointers meet, loop detected, break break; } }
// If loop was not found (e.g., list was not guaranteed to have a loop) // This function assumes a loop exists, so this case shouldn't be hit if used correctly. if (slow == NULL || fast == NULL) { return NULL; // No loop found, or list ended }
// STEP 2: Appoint slow to head // Reset slow pointer to the head of the list slow = head;
// STEP 3: Again Start Traversing Pointers // Move both slow and fast one step at a time. // They will meet at the beginning of the loop. while(slow != fast) { slow = slow->next; fast = fast->next; }
// STEP 4: Got the Beginning Point // Both pointers are now at the start of the loop return slow;}
// main: Program entry point, demonstrates operationsint main() { Node *head = new Node(1); // Create initial node Node *tail = head; // Tail points to head initially
// Build list: 1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 64 -> 128 for(int i=1; i<=7; i++) { insertAtTail(tail, pow(2,i)); } printList(head); // Print original list
// Create a cycle for testing: 128 points to 8 (head->next->next->next) // List: 1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 64 -> 128 -> (points to 8) tail->next = head->next->next->next;
// Find the beginning point of the loop Node* loopStartNode = beginningPoint(head);
// Print the data of the beginning point if (loopStartNode != NULL) { cout << "Beginning point of the loop : " << loopStartNode->data << endl; } else { cout << "No loop found or list is empty." << endl; }
return 0; // Indicate success}1. What is it?
- A linear data structure where elements are stored in nodes.
- Each node has:
data(the actual value)next(a pointer to the next node).
- The last node’s
nextpointer isNULL. - Accessed via a
headpointer (first node) and sometimes atailpointer (last node for efficiency).
2. Core Node Structure
class Node {public: int data; // The value Node* next; // Points to the next node Node(int data) { this->data = data; this->next = NULL; }};- Key:
Node* nextis crucial for linking.
3. Basic Operations (Quick Glance)
-
printList(Node* head):- Purpose: Traverse and display all elements.
- How: Start at
head, loopwhile (head != NULL), printhead->data, thenhead = head->next;. - Edge Case: If
head == NULL, list is empty. - Example:
1->2->3prints “Singly List : 1 2 3”
-
insertAtHead(Node* &head, int data):- Purpose: Add a new node at the beginning.
- How: 1. Create new node. 2. New node’s
nextpoints to oldhead. 3.headbecomes new node. - Key:
headis passed by reference (&). - Example:
2->3+insertAtHead(head, 1)→1->2->3
-
insertAtTail(Node* &tail, int data):- Purpose: Add a new node at the end.
- How: 1. Create new node. 2. Old
tail’snextpoints to new node. 3.tailbecomes new node. - Key:
tailis passed by reference (&). - Example:
1->2+insertAtTail(tail, 3)→1->2->3
-
insertAtMiddle(Node* &head, Node* &tail, int data, int pos):- Purpose: Insert at a specific
pos. - How:
- Handle
pos=1(callinsertAtHead). - Else, traverse (
temp) to node beforepos. - Insert: New node’s
nexttotemp->next,temp->nextto new node. - Update
tailif new node is last.
- Handle
- Example:
10->20->40+insertAtMiddle(..., 30, 3)→10->20->30->40
- Purpose: Insert at a specific
-
deletePosition(Node* &head, int pos):- Purpose: Delete node at specific
pos. - How:
- Handle
pos=1(updatehead,deleteold head). - Else, traverse (
temp) to node beforepos. - Bypass target node (
temp->next = target->next),deletetarget.
- Handle
- Example:
10->20->30+deletePosition(head, 2)→10->30
- Purpose: Delete node at specific
-
deleteValue(Node* &head, int val):- Purpose: Delete the first occurrence of
val. - How:
- Handle
head->data == val(updatehead,deleteold head). - Else, use
prevandtempto findval. - Bypass
temp(prev->next = temp->next),deletetemp.
- Handle
- Example:
10->20->30+deleteValue(head, 20)→10->30
- Purpose: Delete the first occurrence of
4. beginningPoint(Node* head) Function (New!)
-
Purpose: Finds the starting node (entry point) of a loop in a linked list.
-
Pre-requisite: This function assumes that a loop already exists in the linked list. It typically follows a cycle detection function (like
floydDetectLoop). -
Concept: It uses the properties of Floyd’s Cycle-Finding Algorithm (Tortoise and Hare).
- Phase 1: Find the meeting point of the slow and fast pointers.
- Phase 2: Once they meet, move the slow pointer back to the
head. Then, move both slow and fast pointers one step at a time. The point where they meet again is the beginning of the loop.
-
How it works (Step-by-Step):
- Handle Empty List:
if(head == NULL): Returnshead(which isNULL), as no loop can exist.
- Phase 1: Find Intersection Node:
- Initialize
slow = headandfast = head. - Loop
while(slow != NULL && fast != NULL):fast = fast->next;(Fast moves 1 step)slow = slow->next;(Slow moves 1 step)if(fast != NULL) { fast = fast->next; }(Fast moves another step)if(slow == fast) { break; }(If they meet, break the loop - intersection found)
- (Self-correction/Edge Case): If the loop finishes because
sloworfastbecameNULL, it means no loop was found. The code handles this by returningNULLat the end of Phase 1.
- Initialize
- Phase 2: Find Beginning Point:
slow = head;: Reset theslowpointer back to theheadof the list.while(slow != fast): Now, move bothslowandfastpointers one step at a time.slow = slow->next;fast = fast->next;
- They are guaranteed to meet at the beginning of the loop.
- Return Beginning Point:
return slow;(orfast, as they are at the same node).
- Handle Empty List:
-
Example:
List with a Cycle:
head -> 1 -> 2 -> 3 -> 4 -> 5 -> 6^---------<--|(6 points back to 3)- Initial:
slow = 1,fast = 1 - Phase 1 (Finding Intersection):
slowmoves:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 3 -> 4 ...fastmoves:1 -> 3 -> 5 -> 3 -> 5 -> 3 -> 5 ...- They will eventually meet at
3(or4,5,6depending on list length and loop start, but they will meet inside the loop). Let’s assume they meet at node5. slowis at5,fastis at5.break.
- Phase 2 (Finding Beginning):
slowresets tohead(1).fastremains at5.slowmoves:1 -> 2 -> 3fastmoves:5 -> 6 -> 3- They both meet at node
3.
- Return: Node
3.
- Initial:
“Beginning point of the loop : 3”
5. main() Function
- Purpose: Test and demonstrate.
- Flow:
- Creates initial
Node(head). - Populates list using
insertAtTail. - Prints the original list.
- Crucially:
tail->next = head->next->next->next;is uncommented to create a loop (last node points to the node with data8). - Calls
beginningPointto find the loop’s start. - Prints the data of the loop’s beginning point.
- Creates initial