Ref: 2 - added example
This commit is contained in:
74
analysis/04-reverse-linked-list/exapmle/reverse-linked-list/.gitignore
vendored
Normal file
74
analysis/04-reverse-linked-list/exapmle/reverse-linked-list/.gitignore
vendored
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# This file is used to ignore files which are generated
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.autosave
|
||||||
|
*.a
|
||||||
|
*.core
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*_pch.h.cpp
|
||||||
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
|
.#*
|
||||||
|
*.*#
|
||||||
|
core
|
||||||
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
|
||||||
|
# qtcreator generated files
|
||||||
|
*.pro.user*
|
||||||
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
|
# xemacs temporary files
|
||||||
|
*.flc
|
||||||
|
|
||||||
|
# Vim temporary files
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
|
# MinGW generated files
|
||||||
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Reverse Linked List Example
|
||||||
|
|
||||||
|
This directory contains a small standalone C++ example for the classic three-pointer linked list reversal algorithm.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
g++ -std=c++17 -Wall -Wextra -pedantic main.cpp -o reverse_linked_list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./reverse_linked_list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expected Output
|
||||||
|
|
||||||
|
```text
|
||||||
|
Original list:
|
||||||
|
1 -> 2 -> 3 -> 4 -> 5 -> null
|
||||||
|
|
||||||
|
Reversed list:
|
||||||
|
5 -> 4 -> 3 -> 2 -> 1 -> null
|
||||||
|
```
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Original list:
|
||||||
|
1 -> 2 -> 3 -> 4 -> 5 -> null
|
||||||
|
|
||||||
|
Reversed list:
|
||||||
|
5 -> 4 -> 3 -> 2 -> 1 -> null
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += console c++17
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
CONFIG -= qt
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp
|
||||||
Reference in New Issue
Block a user