/** * @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 #include /** * @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 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; }