Skip to content

Commit 914a4f7

Browse files
Muhammadummerrcclausspre-commit-ci[bot]
authored andcommitted
[NEW ALGORITHM] Rotate linked list by K. (TheAlgorithms#9278)
* Rotate linked list by k. * Rotate linked list by k. * updated variable name. * Update data_structures/linked_list/rotate_linked_list_by_k.py Co-authored-by: Christian Clauss <cclauss@me.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update data_structures/linked_list/rotate_linked_list_by_k.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update data_structures/linked_list/rotate_linked_list_by_k.py * Make Node a dataclass --------- Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a30a874 commit 914a4f7

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
5+
6+
@dataclass
7+
class Node:
8+
data: int
9+
next_node: Node | None = None
10+
11+
12+
def print_linked_list(head: Node | None) -> None:
13+
"""
14+
Print the entire linked list iteratively.
15+
16+
This function prints the elements of a linked list separated by '->'.
17+
18+
Parameters:
19+
head (Node | None): The head of the linked list to be printed,
20+
or None if the linked list is empty.
21+
22+
>>> head = insert_node(None, 0)
23+
>>> head = insert_node(head, 2)
24+
>>> head = insert_node(head, 1)
25+
>>> print_linked_list(head)
26+
0->2->1
27+
>>> head = insert_node(head, 4)
28+
>>> head = insert_node(head, 5)
29+
>>> print_linked_list(head)
30+
0->2->1->4->5
31+
"""
32+
if head is None:
33+
return
34+
while head.next_node is not None:
35+
print(head.data, end="->")
36+
head = head.next_node
37+
print(head.data)
38+
39+
40+
def insert_node(head: Node | None, data: int) -> Node:
41+
"""
42+
Insert a new node at the end of a linked list and return the new head.
43+
44+
Parameters:
45+
head (Node | None): The head of the linked list.
46+
data (int): The data to be inserted into the new node.
47+
48+
Returns:
49+
Node: The new head of the linked list.
50+
51+
>>> head = insert_node(None, 10)
52+
>>> head = insert_node(head, 9)
53+
>>> head = insert_node(head, 8)
54+
>>> print_linked_list(head)
55+
10->9->8
56+
"""
57+
new_node = Node(data)
58+
# If the linked list is empty, the new_node becomes the head
59+
if head is None:
60+
return new_node
61+
62+
temp_node = head
63+
while temp_node.next_node:
64+
temp_node = temp_node.next_node
65+
66+
temp_node.next_node = new_node # type: ignore
67+
return head
68+
69+
70+
def rotate_to_the_right(head: Node, places: int) -> Node:
71+
"""
72+
Rotate a linked list to the right by places times.
73+
74+
Parameters:
75+
head: The head of the linked list.
76+
places: The number of places to rotate.
77+
78+
Returns:
79+
Node: The head of the rotated linked list.
80+
81+
>>> rotate_to_the_right(None, places=1)
82+
Traceback (most recent call last):
83+
...
84+
ValueError: The linked list is empty.
85+
>>> head = insert_node(None, 1)
86+
>>> rotate_to_the_right(head, places=1) == head
87+
True
88+
>>> head = insert_node(None, 1)
89+
>>> head = insert_node(head, 2)
90+
>>> head = insert_node(head, 3)
91+
>>> head = insert_node(head, 4)
92+
>>> head = insert_node(head, 5)
93+
>>> new_head = rotate_to_the_right(head, places=2)
94+
>>> print_linked_list(new_head)
95+
4->5->1->2->3
96+
"""
97+
# Check if the list is empty or has only one element
98+
if not head:
99+
raise ValueError("The linked list is empty.")
100+
101+
if head.next_node is None:
102+
return head
103+
104+
# Calculate the length of the linked list
105+
length = 1
106+
temp_node = head
107+
while temp_node.next_node is not None:
108+
length += 1
109+
temp_node = temp_node.next_node
110+
111+
# Adjust the value of places to avoid places longer than the list.
112+
places %= length
113+
114+
if places == 0:
115+
return head # As no rotation is needed.
116+
117+
# Find the new head position after rotation.
118+
new_head_index = length - places
119+
120+
# Traverse to the new head position
121+
temp_node = head
122+
for _ in range(new_head_index - 1):
123+
assert temp_node.next_node
124+
temp_node = temp_node.next_node
125+
126+
# Update pointers to perform rotation
127+
assert temp_node.next_node
128+
new_head = temp_node.next_node
129+
temp_node.next_node = None
130+
temp_node = new_head
131+
while temp_node.next_node:
132+
temp_node = temp_node.next_node
133+
temp_node.next_node = head
134+
135+
assert new_head
136+
return new_head
137+
138+
139+
if __name__ == "__main__":
140+
import doctest
141+
142+
doctest.testmod()
143+
head = insert_node(None, 5)
144+
head = insert_node(head, 1)
145+
head = insert_node(head, 2)
146+
head = insert_node(head, 4)
147+
head = insert_node(head, 3)
148+
149+
print("Original list: ", end="")
150+
print_linked_list(head)
151+
152+
places = 3
153+
new_head = rotate_to_the_right(head, places)
154+
155+
print(f"After {places} iterations: ", end="")
156+
print_linked_list(new_head)

0 commit comments

Comments
 (0)