[+] A1 Starter Files
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
"""CSC111 Winter 2021 Assignment 1: Linked Lists
|
||||
|
||||
Do not change this file -- it will not be submitted, and we will supply our own copy
|
||||
for grading purposes.
|
||||
|
||||
Copyright and Usage Information
|
||||
===============================
|
||||
|
||||
This file is provided solely for the personal and private use of students
|
||||
taking CSC111 at the University of Toronto St. George campus. All forms of
|
||||
distribution of this code, whether as given or with any changes, are
|
||||
expressly prohibited. For more information on copyright for CSC111 materials,
|
||||
please consult our Course Syllabus.
|
||||
|
||||
This file is Copyright (c) 2021 David Liu and Isaac Waller.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Iterable, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class _Node:
|
||||
"""A node in a linked list.
|
||||
|
||||
Note that this is considered a "private class", one which is only meant
|
||||
to be used in this module by the LinkedList class, but not by client code.
|
||||
|
||||
Instance Attributes:
|
||||
- item: The data stored in this node.
|
||||
- next: The next node in the list, if any.
|
||||
"""
|
||||
item: Any
|
||||
next: Optional[_Node] = None # By default, this node does not link to any other node
|
||||
|
||||
|
||||
class LinkedList:
|
||||
"""A linked list implementation of the List ADT.
|
||||
"""
|
||||
# Private Instance Attributes:
|
||||
# - _first: The first node in the linked list, or None if the list is empty.
|
||||
_first: Optional[_Node]
|
||||
|
||||
def __init__(self, items: Iterable) -> None:
|
||||
"""Initialize a new linked list containing the given items.
|
||||
"""
|
||||
self._first = None
|
||||
for item in items:
|
||||
self.append(item)
|
||||
|
||||
def to_list(self) -> list:
|
||||
"""Return a built-in Python list containing the items of this linked list.
|
||||
|
||||
The items in this linked list appear in the same order in the returned list.
|
||||
"""
|
||||
items_so_far = []
|
||||
|
||||
curr = self._first
|
||||
while curr is not None:
|
||||
items_so_far.append(curr.item)
|
||||
curr = curr.next
|
||||
|
||||
return items_so_far
|
||||
|
||||
def __len__(self) -> int:
|
||||
"""Return the number of elements in this list.
|
||||
|
||||
>>> lst = LinkedList([])
|
||||
>>> len(lst) # Equivalent to lst.__len__()
|
||||
0
|
||||
>>> lst = LinkedList([1, 2, 3])
|
||||
>>> len(lst)
|
||||
3
|
||||
"""
|
||||
curr = self._first
|
||||
len_so_far = 0
|
||||
while curr is not None:
|
||||
len_so_far += 1
|
||||
curr = curr.next
|
||||
|
||||
return len_so_far
|
||||
|
||||
def __contains__(self, item: Any) -> bool:
|
||||
"""Return whether item is in this linked list.
|
||||
"""
|
||||
curr = self._first
|
||||
while curr is not None:
|
||||
if curr.item == item:
|
||||
return True
|
||||
|
||||
curr = curr.next
|
||||
return False
|
||||
|
||||
def __getitem__(self, i: int) -> Any:
|
||||
"""Return the item stored at index i in this linked list.
|
||||
|
||||
Raise an IndexError if index i is out of bounds.
|
||||
|
||||
Preconditions:
|
||||
- i >= 0
|
||||
"""
|
||||
curr = self._first
|
||||
curr_index = 0
|
||||
|
||||
while curr is not None:
|
||||
if curr_index == i:
|
||||
return curr.item
|
||||
|
||||
curr = curr.next
|
||||
curr_index = curr_index + 1
|
||||
|
||||
# If we've reached the end of the list and no item has been returned,
|
||||
# the given index is out of bounds.
|
||||
raise IndexError
|
||||
|
||||
def pop(self, i: int) -> Any:
|
||||
"""Remove and return the item at index i.
|
||||
|
||||
Raise IndexError if i >= len(self).
|
||||
|
||||
Preconditions:
|
||||
- i >= 0
|
||||
|
||||
>>> lst = LinkedList([1, 2, 10, 200])
|
||||
>>> lst.pop(1)
|
||||
2
|
||||
>>> lst.to_list()
|
||||
[1, 10, 200]
|
||||
"""
|
||||
if i == 0:
|
||||
if self._first is None:
|
||||
raise IndexError
|
||||
else:
|
||||
item = self._first.item
|
||||
self._first = self._first.next
|
||||
return item
|
||||
else:
|
||||
curr = self._first
|
||||
curr_index = 0
|
||||
|
||||
while not (curr is None or curr_index == i - 1):
|
||||
curr = curr.next
|
||||
curr_index = curr_index + 1
|
||||
|
||||
if curr is None:
|
||||
raise IndexError
|
||||
else:
|
||||
if curr.next is None:
|
||||
raise IndexError
|
||||
else:
|
||||
item = curr.next.item
|
||||
curr.next = curr.next.next
|
||||
return item
|
||||
|
||||
def append(self, item: Any) -> None:
|
||||
"""Add the given item to the end of this linked list.
|
||||
"""
|
||||
new_node = _Node(item)
|
||||
|
||||
if self._first is None:
|
||||
self._first = new_node
|
||||
else:
|
||||
curr = self._first
|
||||
while curr.next is not None:
|
||||
curr = curr.next
|
||||
|
||||
# After the loop, curr is the last node in the LinkedList.
|
||||
assert curr is not None and curr.next is None
|
||||
curr.next = new_node
|
||||
Reference in New Issue
Block a user