From f2e0d02d191ea5d811558a3ea737ac8aab1aa799 Mon Sep 17 00:00:00 2001 From: Immiel Date: Mon, 4 Oct 2021 10:31:13 +0700 Subject: [PATCH 1/2] Added reverse_linked_list.py I looked around and noticed that there's no algorithm that reverse a linked list and returns them. The closest I could find prints them instead of returning them as a function. And so, here it is. The function only have one input and one output. The function works as follows; it pops data from the beginning of input and append them to the beginning of output. For tests, I added doctests for short and concise explanation as to how to use the function, and additional tests if the code is run independently. Hopefully, this piece of code and its documentation could be a suggestion for someone that needs to know how to reverse a linked list. --- .../linked_list/reverse_linked_list.py | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 data_structures/linked_list/reverse_linked_list.py diff --git a/data_structures/linked_list/reverse_linked_list.py b/data_structures/linked_list/reverse_linked_list.py new file mode 100644 index 000000000000..6f7b7ed9f63b --- /dev/null +++ b/data_structures/linked_list/reverse_linked_list.py @@ -0,0 +1,134 @@ +""" +Linked List is described as a bunch of nodes connected to one another. +For this scenario, this is intended for a single Linked List. +""" + +from typing import Any, Optional + + +class Node: + """ + This class forms the backbone of a data structure called Linked List. + """ + + def __init__(self, item: Any, next: Any = None) -> None: + self.item = item + self.next = next + + def __repr__(self) -> str: + """ + This is here for debugging/testing purposes. This is used to convert the + nodes and its branch to string. + """ + if self.next is not None: + return f"{str(self.item)}, {self.next.__repr__()}" + else: + return str(self.item) + + +def reverse_linked_list(input: Optional[Node]) -> Optional[Node]: + """ + This function reverse the order of the given linked list. + >>> reverse_linked_list(Node(1, Node(2, Node(3)))) + 3, 2, 1 + >>> reverse_linked_list(None) # it returns None + >>> reverse_linked_list(Node('First', Node('Second'))) + Second, First + """ + # If input is None, return None. + if input is None: + return None + + # This algorithm works by popping items from input, and then pushing + # the popped item to output. + + temp = input # backup the input. We don't want to change the input. + + # Pop the first node. + output = Node(temp.item) + temp = temp.next + + # Pop data off temp and push them into output until temp has no more data. + while temp is not None: + output = Node(temp.item, output) + temp = temp.next + + # Return the output + return output + + +if __name__ == "__main__": + """ + Running this file independently will perform assertion. + + Input and Expected tests: + - [1, 2, 3, 4, 5] -> [5, 4, 3, 2, 1] + - [-9, 100, 7, 5555, 0] -> [0, 5555, 7, 100, -9] + - [-100, -200, -300] -> [-300, -200, -100] + - None -> None + - [10] -> [10] + - [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 0] -> + [0, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10] + """ + + import doctest + + doctest.testmod() + + input = [ + Node(1, Node(2, Node(3, Node(4, Node(5))))), + Node(-9, Node(100, Node(7, Node(5555, Node(0))))), + Node(-100, Node(-200, Node(-300))), + None, + Node(10), + Node( + 10, + Node( + 20, + Node( + 30, + Node( + 40, + Node( + 50, + Node(60, Node(70, Node(80, Node(90, Node(100, Node(0)))))), + ), + ), + ), + ), + ), + ] + + expected = [ + Node(5, Node(4, Node(3, Node(2, Node(1))))), + Node(0, Node(5555, Node(7, Node(100, Node(-9))))), + Node(-300, Node(-200, Node(-100))), + None, + Node(10), + Node( + 0, + Node( + 100, + Node( + 90, + Node( + 80, + Node( + 70, + Node(60, Node(50, Node(40, Node(30, Node(20, Node(10)))))), + ), + ), + ), + ), + ), + ] + + # Assert them here. + for i, e in zip(input, expected): + result = reverse_linked_list(i) + assert str(result) == str( + e + ), f"Assert Failed. Result: [{str(result)}]. Expected: [{str(e)}]" + + # Indicate successful test. + print("Assertion for Reverse Linked List is successful.") From 625792ad3c7f313d644cfbc4226a4ff834607d87 Mon Sep 17 00:00:00 2001 From: Immiel Date: Mon, 4 Oct 2021 10:38:30 +0700 Subject: [PATCH 2/2] Added doctest to __repr__ --- data_structures/linked_list/reverse_linked_list.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/linked_list/reverse_linked_list.py b/data_structures/linked_list/reverse_linked_list.py index 6f7b7ed9f63b..97ce68401a72 100644 --- a/data_structures/linked_list/reverse_linked_list.py +++ b/data_structures/linked_list/reverse_linked_list.py @@ -19,6 +19,8 @@ def __repr__(self) -> str: """ This is here for debugging/testing purposes. This is used to convert the nodes and its branch to string. + >>> Node(10, Node(20)).__repr__() + '10, 20' """ if self.next is not None: return f"{str(self.item)}, {self.next.__repr__()}"