mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
feat: Add reverse linked list algorithim (#1596)
* add: reverse linked list algorithim * updating DIRECTORY.md * clang-format and clang-tidy fixes for5cac47c9
* Update data_structures/reverse_a_linked_list.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update data_structures/reverse_a_linked_list.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update the description in data_structures/reverse_a_linked_list.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for19b4a937
* Updating data_structures/reverse_a_linked_list.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * add:test for the reversing algorithim * fix: synatx changes * docs :added an external link for explanation of the algorithim * fix: suggested changes * fix: chamges in the code * docs : changes required in the docs * docs :fix indentation * fix : ouptut statement changes * fix: clang-tidy warnings * formatting filenamesf7695035
* updating DIRECTORY.md * clang-format and clang-tidy fixes forf7695035
* fix : display function removed * updating DIRECTORY.md * clang-format and clang-tidy fixes for38547be2
* fix: changed the data types * clang-format and clang-tidy fixes for3b2e68c2
* docs : documentation fixes Co-authored-by: David Leal <halfpacho@gmail.com> * docs : documentation changes Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for57953be1
* docs: fix changes Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes fordb8e74a9
* fix : display changes Co-authored-by: ERR ! <75872316+amino19@users.noreply.github.com> * fix : added try block * fix: try-catch block * fix :merge conflict * docs:documentation changes * added more efficient test cases * clang-format and clang-tidy fixes for83ee6e44
* Update data_structures/reverse_a_linked_list.cpp Co-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: Abhinn Mishra <49574460+mishraabhinn@users.noreply.github.com> Co-authored-by: ERR ! <75872316+amino19@users.noreply.github.com>
This commit is contained in:
parent
5245b3e4a9
commit
f7a5aecce5
@ -52,6 +52,7 @@
|
|||||||
* [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linkedlist.cpp)
|
* [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linkedlist.cpp)
|
||||||
* [Queue Using Two Stacks](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_two_stacks.cpp)
|
* [Queue Using Two Stacks](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_two_stacks.cpp)
|
||||||
* [Rb Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/rb_tree.cpp)
|
* [Rb Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/rb_tree.cpp)
|
||||||
|
* [Reverse A Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/reverse_a_linked_list.cpp)
|
||||||
* [Skip List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/skip_list.cpp)
|
* [Skip List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/skip_list.cpp)
|
||||||
* [Sparse Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/sparse_table.cpp)
|
* [Sparse Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/sparse_table.cpp)
|
||||||
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h)
|
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h)
|
||||||
|
208
data_structures/reverse_a_linked_list.cpp
Normal file
208
data_structures/reverse_a_linked_list.cpp
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Implementation of [Reversing
|
||||||
|
* a single linked list](https://simple.wikipedia.org/wiki/Linked_list)
|
||||||
|
* @details
|
||||||
|
* The linked list is a data structure used for holding a sequence of
|
||||||
|
* values, which can be added, displayed, reversed, or removed.
|
||||||
|
* ### Algorithm
|
||||||
|
* Values can be added by iterating to the end of a list (by following
|
||||||
|
* the pointers) starting from the first link. Whichever link points to null
|
||||||
|
* is considered the last link and is pointed to the new value.
|
||||||
|
*
|
||||||
|
* Linked List can be reversed by using 3 pointers: current, previous, and
|
||||||
|
* next_node; we keep iterating until the last node. Meanwhile, before changing
|
||||||
|
* to the next of current, we store it in the next_node pointer, now we store
|
||||||
|
* the prev pointer in the current of next, this is where the actual reversal
|
||||||
|
* happens. And then we move the prev and current pointers one step forward.
|
||||||
|
* Then the head node is made to point to the last node (prev pointer) after
|
||||||
|
* completion of an iteration.
|
||||||
|
|
||||||
|
* [A graphic explanation and view of what's happening behind the
|
||||||
|
*scenes](https://drive.google.com/file/d/1pM5COF0wx-wermnNy_svtyZquaCUP2xS/view?usp=sharing)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cassert> /// for assert
|
||||||
|
#include <iostream> /// for I/O operations
|
||||||
|
#include <memory> /// for dynamic memory
|
||||||
|
#include <new> /// for managing dynamic storage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace data_structures
|
||||||
|
* @brief Data Structures algorithms
|
||||||
|
*/
|
||||||
|
namespace data_structures {
|
||||||
|
/**
|
||||||
|
* @namespace linked_list
|
||||||
|
* @brief Functions for singly linked list algorithm
|
||||||
|
*/
|
||||||
|
namespace linked_list {
|
||||||
|
/**
|
||||||
|
* A Node class containing a value and pointer to another link
|
||||||
|
*/
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
int32_t val; /// value of the current link
|
||||||
|
Node *next; /// pointer to the next value on the list
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list class containing a sequence of links
|
||||||
|
*/
|
||||||
|
class list {
|
||||||
|
private:
|
||||||
|
Node *head; // link before the actual first element
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* List constructor. Initializes the first link.
|
||||||
|
*/
|
||||||
|
list() {
|
||||||
|
head = nullptr; // Initialize the first link
|
||||||
|
}
|
||||||
|
bool isEmpty();
|
||||||
|
void insert(int32_t new_elem);
|
||||||
|
void reverseList();
|
||||||
|
void display();
|
||||||
|
int32_t top();
|
||||||
|
int32_t last();
|
||||||
|
int32_t traverse(int32_t index);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function that checks if the list is empty
|
||||||
|
* @returns true if the list is empty
|
||||||
|
* @returns false if the list is not empty
|
||||||
|
*/
|
||||||
|
bool list::isEmpty() { return head == nullptr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function that adds a new element at the end of the list
|
||||||
|
* @param new_elem element be added at the end of the list
|
||||||
|
*/
|
||||||
|
void list::insert(int32_t n) {
|
||||||
|
try {
|
||||||
|
Node *new_node = new Node();
|
||||||
|
Node *temp = nullptr;
|
||||||
|
new_node->val = n;
|
||||||
|
new_node->next = nullptr;
|
||||||
|
if (isEmpty()) {
|
||||||
|
head = new_node;
|
||||||
|
} else {
|
||||||
|
temp = head;
|
||||||
|
while (temp->next != nullptr) {
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
|
temp->next = new_node;
|
||||||
|
}
|
||||||
|
} catch (std::bad_alloc &exception) {
|
||||||
|
std::cerr << "bad_alloc detected: " << exception.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function for reversing a list
|
||||||
|
* @brief Using the current, previous, and next pointer.
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
void list::reverseList() {
|
||||||
|
Node *curr = head;
|
||||||
|
Node *prev = nullptr, *next_node = nullptr;
|
||||||
|
while (curr != nullptr) {
|
||||||
|
next_node = curr->next;
|
||||||
|
curr->next = prev;
|
||||||
|
prev = curr;
|
||||||
|
curr = next_node;
|
||||||
|
}
|
||||||
|
head = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to find the top element of the list
|
||||||
|
* @returns the top element of the list
|
||||||
|
*/
|
||||||
|
int32_t list::top() {
|
||||||
|
try {
|
||||||
|
if (!isEmpty()) {
|
||||||
|
return head->val;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
std::cerr << "List is empty" << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Utility function to find the last element of the list
|
||||||
|
* @returns the last element of the list
|
||||||
|
*/
|
||||||
|
int32_t list::last() {
|
||||||
|
try {
|
||||||
|
if (!isEmpty()) {
|
||||||
|
Node *t = head;
|
||||||
|
while (t->next != nullptr) {
|
||||||
|
t = t->next;
|
||||||
|
}
|
||||||
|
return t->val;
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
std::cerr << "List is empty" << e.what() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Utility function to find the i th element of the list
|
||||||
|
* @returns the i th element of the list
|
||||||
|
*/
|
||||||
|
int32_t list::traverse(int index) {
|
||||||
|
Node *current = head;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while (current != nullptr) {
|
||||||
|
if (count == index) {
|
||||||
|
return (current->val);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we get to this line,the caller was asking for a non-existent element
|
||||||
|
so we assert fail */
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace linked_list
|
||||||
|
} // namespace data_structures
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Self-test implementations
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
static void test() {
|
||||||
|
data_structures::linked_list::list L;
|
||||||
|
// 1st test
|
||||||
|
L.insert(11);
|
||||||
|
L.insert(12);
|
||||||
|
L.insert(15);
|
||||||
|
L.insert(10);
|
||||||
|
L.insert(-12);
|
||||||
|
L.insert(-20);
|
||||||
|
L.insert(18);
|
||||||
|
assert(L.top() == 11);
|
||||||
|
assert(L.last() == 18);
|
||||||
|
L.reverseList();
|
||||||
|
// Reversal Testing
|
||||||
|
assert(L.top() == 18);
|
||||||
|
assert(L.traverse(1) == -20);
|
||||||
|
assert(L.traverse(2) == -12);
|
||||||
|
assert(L.traverse(3) == 10);
|
||||||
|
assert(L.traverse(4) == 15);
|
||||||
|
assert(L.traverse(5) == 12);
|
||||||
|
assert(L.last() == 11);
|
||||||
|
std::cout << "All tests have successfully passed!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main function
|
||||||
|
* @returns 0 on exit
|
||||||
|
*/
|
||||||
|
int main() {
|
||||||
|
test(); // run self-test implementations
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user