Ref: 2 Rename folder to follow previous articles
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* @file main.cpp
|
||||
* @brief Demonstrates the classic three-pointer algorithm for reversing a singly linked list.
|
||||
*
|
||||
* This example is intentionally small and self-contained.
|
||||
* It is not meant to show that reversing linked lists is a common production task.
|
||||
* Instead, it documents the interview pattern clearly enough that a reader unfamiliar
|
||||
* with it can compile the program, run it, and inspect the output.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <initializer_list>
|
||||
|
||||
/**
|
||||
* @brief A minimal singly linked list node.
|
||||
*
|
||||
* Each node stores an integer value and a pointer to the next node.
|
||||
* The last node in the list has @c next equal to @c nullptr.
|
||||
*/
|
||||
struct Node {
|
||||
int value; ///< Payload stored in the node.
|
||||
Node *next; ///< Pointer to the next node, or nullptr for the last node.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Appends a new value to the end of the list.
|
||||
*
|
||||
* @param head Reference to the head pointer of the list.
|
||||
* @param value Value to store in the new node.
|
||||
*
|
||||
* This helper is used only to build the demonstration list.
|
||||
* It keeps the example simple and avoids using STL containers for the list itself,
|
||||
* because the goal is to demonstrate raw pointer manipulation.
|
||||
*/
|
||||
void appendNode (Node *&head, int value) {
|
||||
Node *node = new Node{value, nullptr};
|
||||
|
||||
if (head == nullptr) {
|
||||
head = node;
|
||||
return;
|
||||
}
|
||||
|
||||
Node *current = head;
|
||||
|
||||
while (current->next != nullptr)
|
||||
current = current->next;
|
||||
|
||||
current->next = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a linked list from an initializer list.
|
||||
*
|
||||
* @param values Values to insert into the list in the given order.
|
||||
* @return Pointer to the first node of the created list.
|
||||
*
|
||||
* The caller owns the returned list and must release it with freeList().
|
||||
*/
|
||||
Node *createList (std::initializer_list<int> values) {
|
||||
Node *head = nullptr;
|
||||
|
||||
for (int value : values)
|
||||
appendNode (head, value);
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the list without modifying it.
|
||||
*
|
||||
* @param head Pointer to the first node of the list.
|
||||
*
|
||||
* Output example:
|
||||
* @code
|
||||
* 1 -> 2 -> 3 -> 4 -> null
|
||||
* @endcode
|
||||
*/
|
||||
void printList (const Node *head) {
|
||||
const Node *current = head;
|
||||
|
||||
while (current != nullptr) {
|
||||
std::cout << current->value << " -> ";
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
std::cout << "null" << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverses a singly linked list in place.
|
||||
*
|
||||
* @param head Pointer to the first node of the original list.
|
||||
* @return Pointer to the first node of the reversed list.
|
||||
*
|
||||
* This is the classic three-pointer interview algorithm.
|
||||
*
|
||||
* The three pointers are:
|
||||
*
|
||||
* - @c previous — the already reversed part of the list
|
||||
* - @c current — the node we are processing right now
|
||||
* - @c next — the original next node saved before we overwrite @c current->next
|
||||
*
|
||||
* Why @c next is necessary:
|
||||
*
|
||||
* In a singly linked list, each node only knows where the next node is.
|
||||
* When we execute:
|
||||
*
|
||||
* @code
|
||||
* current->next = previous;
|
||||
* @endcode
|
||||
*
|
||||
* we destroy the original forward link.
|
||||
* Without saving it first, the rest of the list would be lost.
|
||||
*
|
||||
* The algorithm works by moving one node at a time from the original forward chain
|
||||
* into the reversed chain.
|
||||
*
|
||||
* Initial state:
|
||||
*
|
||||
* @code
|
||||
* previous = null
|
||||
* current = 1 -> 2 -> 3 -> 4 -> null
|
||||
* @endcode
|
||||
*
|
||||
* After processing node 1:
|
||||
*
|
||||
* @code
|
||||
* previous = 1 -> null
|
||||
* current = 2 -> 3 -> 4 -> null
|
||||
* @endcode
|
||||
*
|
||||
* After processing node 2:
|
||||
*
|
||||
* @code
|
||||
* previous = 2 -> 1 -> null
|
||||
* current = 3 -> 4 -> null
|
||||
* @endcode
|
||||
*
|
||||
* When @c current becomes @c nullptr, @c previous points to the new head.
|
||||
*
|
||||
* Complexity:
|
||||
*
|
||||
* - Time: O(n), because each node is visited once.
|
||||
* - Extra memory: O(1), because only a fixed number of pointers is used.
|
||||
*/
|
||||
Node *reverseList (Node *head) {
|
||||
Node *previous = nullptr;
|
||||
Node *current = head;
|
||||
|
||||
while (current != nullptr) {
|
||||
/*
|
||||
* Save the original next node before changing current->next.
|
||||
* Without this line, the rest of the list would become unreachable.
|
||||
*/
|
||||
Node *next = current->next;
|
||||
|
||||
/*
|
||||
* Reverse the direction of the link.
|
||||
* The current node now points to the already reversed part.
|
||||
*/
|
||||
current->next = previous;
|
||||
|
||||
/*
|
||||
* Move previous forward.
|
||||
* The current node becomes the new head of the reversed part.
|
||||
*/
|
||||
previous = current;
|
||||
|
||||
/*
|
||||
* Continue with the node that originally followed current.
|
||||
*/
|
||||
current = next;
|
||||
}
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases all nodes in the list.
|
||||
*
|
||||
* @param head Pointer to the first node of the list.
|
||||
*
|
||||
* This function is separated from the reversal and printing logic.
|
||||
* It exists only because this example uses raw @c new to keep the node structure explicit.
|
||||
*/
|
||||
void freeList (Node *head) {
|
||||
Node *current = head;
|
||||
|
||||
while (current != nullptr) {
|
||||
Node *next = current->next;
|
||||
delete current;
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program entry point.
|
||||
*
|
||||
* Builds a small list, prints it, reverses it, prints it again,
|
||||
* and finally releases all allocated nodes.
|
||||
*/
|
||||
int main() {
|
||||
Node *list = createList ({1, 2, 3, 4, 5});
|
||||
|
||||
std::cout << "Original list:" << std::endl;
|
||||
printList (list);
|
||||
|
||||
list = reverseList (list);
|
||||
|
||||
std::cout << "\nReversed list:" << std::endl;
|
||||
printList (list);
|
||||
|
||||
freeList (list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user