-
Notifications
You must be signed in to change notification settings - Fork 2
feat(data structures, linked list) reorder list #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| from typing import Optional | ||
| from datastructures.linked_lists.singly_linked_list.node import SingleNode | ||
|
|
||
|
|
||
| def merge_and_weave( | ||
| first_half_head: SingleNode, second_half_head: SingleNode | ||
| ) -> Optional[SingleNode]: | ||
| """ | ||
| Merges and weaves the first half and the reversed second half of the linked list in place. | ||
| Args: | ||
| first_half_head: head node of the first half of the linked list | ||
| second_half_head: head node of the reversed second half of the linked list | ||
| Returns: | ||
| head node of the merged and weaved linked list | ||
| """ | ||
| if first_half_head is None or second_half_head is None: | ||
| return None | ||
|
Comment on lines
+16
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cd datastructures/linked_lists/singly_linked_list && find . -name "*.py" | head -20Repository: BrianLusina/PythonSnips Length of output: 611 🏁 Script executed: cat -n datastructures/linked_lists/singly_linked_list/single_linked_list_utils.py | head -80Repository: BrianLusina/PythonSnips Length of output: 2483 🏁 Script executed: # Also search for usage in single_linked_list.py
grep -n "merge_and_weave\|reorder" datastructures/linked_lists/singly_linked_list/single_linked_list.py | head -20Repository: BrianLusina/PythonSnips Length of output: 259 🏁 Script executed: sed -n '985,1025p' datastructures/linked_lists/singly_linked_list/single_linked_list.pyRepository: BrianLusina/PythonSnips Length of output: 1636 Fix early-return logic for edge cases in The function returns if first_half_head is None:
return second_half_head
if second_half_head is None:
return first_half_head🤖 Prompt for AI Agents |
||
|
|
||
| p1 = first_half_head | ||
| p2 = second_half_head | ||
|
|
||
| while p2: | ||
| # save the pointer 1 next node to not loose it | ||
| p1_next = p1.next | ||
| p2_next = p2.next | ||
|
|
||
| # now we can move the pointers | ||
| p1.next = p2 | ||
| p2.next = p1_next | ||
|
|
||
| p1, p2 = p1_next, p2_next | ||
|
|
||
| return first_half_head | ||
|
|
||
|
|
||
| def reverse_list(head: SingleNode) -> Optional[SingleNode]: | ||
| """ | ||
| Reverses a linked list given the head node | ||
| Args: | ||
| head Node: the head node of the linked list | ||
| Returns: | ||
| Optional[Node]: the new head node of the reversed linked list | ||
| """ | ||
| if head is None or head.next is None: | ||
| return head | ||
|
|
||
| # track previous node, so we can point our next pointer to it | ||
| previous = None | ||
| # track node to loop through | ||
| current_node = head | ||
|
|
||
| while current_node: | ||
| # track the next node to not lose it while adjusting pointers | ||
| nxt = current_node.next | ||
|
|
||
| # set the next pointer to the node behind it, previous | ||
| current_node.next = previous | ||
|
|
||
| # adjust the new previous node to the current node for subsequent loops | ||
| previous = current_node | ||
|
|
||
| # move our node pointer up to the next node in front of it | ||
| current_node = nxt | ||
|
|
||
| # return the new tail of the k-group which is our head | ||
| return previous | ||
|
Comment on lines
+36
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Eliminate code duplication for reverse_list. This
Consider consolidating to a single canonical implementation (likely the static utility in Based on learnings, code duplication should be avoided to reduce maintenance burden and potential for divergence. 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import unittest | ||
| from typing import List | ||
| from parameterized import parameterized | ||
| from datastructures.linked_lists.singly_linked_list.single_linked_list import ( | ||
| SinglyLinkedList, | ||
| ) | ||
|
|
||
| TEST_CASES = [ | ||
| ([1, 2, 3, 4, 5], [1, 5, 2, 4, 3]), | ||
| ([1, 2, 3, 4], [1, 4, 2, 3]), | ||
| ([1, 1, 2, 2, 3, -1, 10, 12], [1, 12, 1, 10, 2, -1, 2, 3]), | ||
| ([10, 20, -22, 21, -12], [10, -12, 20, 21, -22]), | ||
| ([1, 3, 5, 7, 9, 10, 8, 6, 4, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), | ||
| ([1, 2, 3, 4, 5, 6], [1, 6, 2, 5, 3, 4]), | ||
| ( | ||
| [7, 0, 10, 13, 12, 19, 1, 3, 6, 7, 4, 2, 11], | ||
| [7, 11, 0, 2, 10, 4, 13, 7, 12, 6, 19, 3, 1], | ||
| ), | ||
| ([0, 8, 3, 1, 2, 7], [0, 7, 8, 2, 3, 1]), | ||
| ([7, 4, 6, 1, 5, 8], [7, 8, 4, 5, 6, 1]), | ||
| ([9, 0, 8, 2], [9, 2, 0, 8]), | ||
| ([6, 8, 7], [6, 7, 8]), | ||
| ] | ||
|
|
||
|
|
||
| class ReorderListTestCase(unittest.TestCase): | ||
| @parameterized.expand(TEST_CASES) | ||
| def test_reorder_list(self, input_list: List[int], expected_output: List[int]): | ||
| linked_list = SinglyLinkedList() | ||
| for data in input_list: | ||
| linked_list.append(data) | ||
|
|
||
| actual = linked_list.reorder_list() | ||
| self.assertIsNotNone(actual) | ||
|
|
||
| # since the head node is returned, we want the values of the linked list and not just the head node | ||
| # to check that the actual reordering worked | ||
| actual_list: List[int] = [] | ||
| curr = actual | ||
| while curr: | ||
| actual_list.append(curr.data) | ||
| curr = curr.next | ||
|
|
||
| self.assertEqual(expected_output, actual_list) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| from typing import List | ||
| import unittest | ||
| from parameterized import parameterized | ||
| from datastructures.linked_lists.singly_linked_list.single_linked_list import ( | ||
| SinglyLinkedList, | ||
| ) | ||
| from datastructures.linked_lists.singly_linked_list.single_linked_list_utils import ( | ||
| merge_and_weave, | ||
| ) | ||
|
|
||
| TEST_CASES = [ | ||
| ([1, 2, 3], [6, 5, 4], [1, 6, 2, 5, 3, 4]), | ||
| ([1, 2, 3], [4, 5], [1, 4, 2, 5, 3]), | ||
| ] | ||
|
|
||
|
|
||
| class MergeAndWeaveSinglyLinkedListTestCase(unittest.TestCase): | ||
| def test_return_none_for_empty_linked_list(self): | ||
| """should return none for an empty linked list when attempting to reverse""" | ||
| linked_list_one = SinglyLinkedList() | ||
| linked_list_two = SinglyLinkedList() | ||
|
|
||
| actual = merge_and_weave(linked_list_one.head, linked_list_two.head) | ||
| self.assertIsNone(actual) | ||
|
|
||
| @parameterized.expand(TEST_CASES) | ||
| def test_merge_and_weave( | ||
| self, list_one_data: List[int], list_two_data: List[int], expected: List[int] | ||
| ): | ||
| linked_list_one = SinglyLinkedList() | ||
| # add the data to the linked list | ||
| for d in list_one_data: | ||
| linked_list_one.append(d) | ||
|
|
||
| linked_list_two = SinglyLinkedList() | ||
| # add the data to the linked list | ||
| for d in list_two_data: | ||
| linked_list_two.append(d) | ||
|
|
||
| actual = merge_and_weave(linked_list_one.head, linked_list_two.head) | ||
|
|
||
| actual_list: List[int] = [] | ||
| curr = actual | ||
| while curr: | ||
| actual_list.append(curr.data) | ||
| curr = curr.next | ||
|
|
||
| # perform assertion | ||
| self.assertEqual(expected, actual_list) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: BrianLusina/PythonSnips
Length of output: 1556
Fix incorrect method call on line 1013.
self.reverse_list(second_half_head)attempts to callreverse_listas a class method, butreverse_listis imported as a standalone function (line 8), not a method ofSinglyLinkedList. This will cause anAttributeErrorat runtime.📝 Committable suggestion
🤖 Prompt for AI Agents