Source code for physdes.rdllist
from typing import List, TypeVar
from mywheel.dllist import Dllink # type: ignore
T = TypeVar("T")
[docs]
class RDllIterator:
"""The `RobinIterator` class is an iterator that iterates over a singly linked list starting from a
given node.
Examples:
>>> cdll = RDllist(5)
>>> it = RDllIterator(cdll[2])
>>> for vlink in it:
... print(vlink.data)
3
4
0
1
"""
__slots__ = ("cur", "stop")
cur: Dllink[int]
stop: Dllink[int]
[docs]
def __init__(self, node: Dllink[int]) -> None:
"""
The function initializes the current and stop pointers to the given node.
:param node: The `node` parameter is an instance of the `SlNode` class. It represents a node in a singly linked list
:type node: Dllink[int]
"""
self.cur = self.stop = node
[docs]
def __iter__(self) -> "RDllIterator":
"""
The function returns an instance of the RobinIterator class.
:return: The `__iter__` method is returning an instance of the `RobinIterator` class.
"""
return self
[docs]
def next(self) -> Dllink[int]:
"""
The `next` function returns the next element in a linked list and raises a `StopIteration` exception
if there are no more elements.
:return: The method is returning an integer value.
"""
self.cur = self.cur.next
if self.cur != self.stop:
return self.cur
else:
raise StopIteration()
[docs]
def __next__(self) -> Dllink[int]:
"""
The __next__ function returns the next item in the iterator.
:return: The `next()` method is being called and its return value is being returned.
"""
return self.next()
[docs]
class RDllist:
"""Round-Robin Doubly Linked List implementation
Examples:
>>> cdll = RDllist(5)
>>> for vlink in cdll:
... print(vlink.data)
1
2
3
4
>>> cdll = RDllist(5, reverse=True)
>>> for vlink in cdll:
... print(vlink.data)
4
3
2
1
"""
__slots__ = "cycle"
cycle: List[Dllink[int]]
[docs]
def __init__(self, num_nodes: int, reverse: bool = False) -> None:
"""
Initialize a Round-Robin doubly linked list.
The head node contains no data and serves as a sentinel.
:param num_nodes: The `num_nodes` parameter is an integer that represents the number of parts in the cycle
:type num_nodes: int
"""
self.cycle = list(Dllink(k) for k in range(num_nodes))
dl2 = self.cycle[-1]
if not reverse:
for dl1 in self.cycle:
dl2.next = dl1
dl1.prev = dl2
dl2 = dl1
else:
for dl1 in self.cycle:
dl2.prev = dl1
dl1.next = dl2
dl2 = dl1
[docs]
def __getitem__(self, k: int) -> Dllink[int]:
"""
The `__getitem__` function returns the item at the given index.
:param k: The `k` parameter is an integer that represents the index of the item to be retrieved
:type k: int
:return: The item at the given index.
Examples:
>>> cdll = RDllist(5)
>>> cdll[2].data
2
"""
return self.cycle[k]
[docs]
def from_node(self, k: int) -> RDllIterator:
"""
The `from_node` function returns an iterator that starts from the given node.
:param k: The `k` parameter is an integer that represents the starting node
:type k: int
:return: An iterator that starts from the given node.
Examples:
>>> cdll = RDllist(5)
>>> it = cdll.from_node(2)
>>> for vlink in it:
... print(vlink.data)
3
4
0
1
"""
return RDllIterator(self.cycle[k])
[docs]
def __iter__(self) -> RDllIterator:
"""
The `__iter__` function returns an iterator object for a doubly linked list.
"""
return self.from_node(0)
# Example usage and tests
if __name__ == "__main__":
# Create a new Round-Robin doubly linked list
cdll = RDllist(10)
for vlink in cdll.from_node(3):
print(vlink.data)
print("---------")
print(cdll[4].data)