Created
March 21, 2021 18:42
-
-
Save Clivern/232d8bf9b9a0ff30e3339d9c8c086600 to your computer and use it in GitHub Desktop.
Python Linked Lists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import bisect | |
| from heapq import * | |
| """ | |
| Linked Lists | |
| A linked list is an ordered collection of values. | |
| Linked lists are similar to arrays in the sense that they contain objects in a linear order. | |
| However they differ from arrays in their memory layout. | |
| Arrays are contiguous data structures and they’re composed of fixed-size data records stored in adjoining blocks of memory. | |
| Linked lists, however, are made up of data records linked together by pointers. | |
| https://dbader.org/blog/python-linked-list | |
| """ | |
| class SListNode(): | |
| def __init__(self, data=None, next=None): | |
| self.data = data | |
| self.next = next | |
| def __repr__(self): | |
| return repr(self.data) | |
| class DListNode(): | |
| """ | |
| A node in a doubly-linked list. | |
| """ | |
| def __init__(self, data=None, prev=None, next=None): | |
| self.data = data | |
| self.prev = prev | |
| self.next = next | |
| def __repr__(self): | |
| return repr(self.data) | |
| class SinglyLinkedList: | |
| def __init__(self): | |
| """ | |
| Create a new singly-linked list. | |
| Takes O(1) time. | |
| """ | |
| self.head = None | |
| def __repr__(self): | |
| """ | |
| Return a string representation of the list. | |
| Takes O(n) time. | |
| """ | |
| nodes = [] | |
| curr = self.head | |
| while curr: | |
| nodes.append(repr(curr)) | |
| curr = curr.next | |
| return '[' + ', '.join(nodes) + ']' | |
| def prepend(self, data): | |
| """ | |
| Insert a new element at the beginning of the list. | |
| Takes O(1) time. | |
| """ | |
| self.head = SListNode(data=data, next=self.head) | |
| def append(self, data): | |
| """ | |
| Insert a new element at the end of the list. | |
| Takes O(n) time. | |
| https://www.hackerrank.com/challenges/30-linked-list/problem | |
| """ | |
| if not self.head: | |
| self.head = SListNode(data=data) | |
| return | |
| curr = self.head | |
| while curr.next: | |
| curr = curr.next | |
| curr.next = SListNode(data=data) | |
| def insert(self, data): | |
| """ | |
| Insert a new element at the end of the list. | |
| Takes O(n) time. | |
| """ | |
| if not self.head: | |
| self.head = SListNode(data=data) | |
| return | |
| curr = self.head | |
| while curr.next: | |
| curr = curr.next | |
| curr.next = SListNode(data=data) | |
| def find(self, key): | |
| """ | |
| Search for the first element with `data` matching | |
| `key`. Return the element or `None` if not found. | |
| Takes O(n) time. | |
| """ | |
| curr = self.head | |
| while curr and curr.data != key: | |
| curr = curr.next | |
| return curr # Will be None if not found | |
| def remove(self, key): | |
| """ | |
| Remove the first occurrence of `key` in the list. | |
| Takes O(n) time. | |
| """ | |
| # Find the element and keep a | |
| # reference to the element preceding it | |
| curr = self.head | |
| prev = None | |
| while curr and curr.data != key: | |
| prev = curr | |
| curr = curr.next | |
| # Unlink it from the list | |
| if prev is None: | |
| self.head = curr.next | |
| elif curr: | |
| prev.next = curr.next | |
| curr.next = None | |
| def reverse(self): | |
| """ | |
| Reverse the list in-place. | |
| Takes O(n) time. | |
| """ | |
| curr = self.head | |
| prev_node = None | |
| next_node = None | |
| while curr: | |
| next_node = curr.next | |
| curr.next = prev_node | |
| prev_node = curr | |
| curr = next_node | |
| self.head = prev_node | |
| def remove_duplicates(self): | |
| """ | |
| Your remove_duplicates function should return the head of the updated linked list. after removing duplicates | |
| https://www.hackerrank.com/challenges/30-linked-list-deletion/problem | |
| """ | |
| if not self.head: | |
| return None | |
| n = self.head | |
| while n.next: | |
| if n.data == n.next.data: | |
| n.next = n.next.next | |
| else: | |
| n = n.next | |
| return self.head | |
| class DoublyLinkedList(): | |
| def __init__(self): | |
| """ | |
| Create a new doubly linked list. | |
| Takes O(1) time. | |
| """ | |
| self.head = None | |
| def __repr__(self): | |
| """ | |
| Return a string representation of the list. | |
| Takes O(n) time. | |
| """ | |
| nodes = [] | |
| curr = self.head | |
| while curr: | |
| nodes.append(repr(curr)) | |
| curr = curr.next | |
| return '[' + ', '.join(nodes) + ']' | |
| def prepend(self, data): | |
| """ | |
| Insert a new element at the beginning of the list. | |
| Takes O(1) time. | |
| """ | |
| new_head = DListNode(data=data, next=self.head) | |
| if self.head: | |
| self.head.prev = new_head | |
| self.head = new_head | |
| def append(self, data): | |
| """ | |
| Insert a new element at the end of the list. | |
| Takes O(n) time. | |
| """ | |
| if not self.head: | |
| self.head = DListNode(data=data) | |
| return | |
| curr = self.head | |
| while curr.next: | |
| curr = curr.next | |
| curr.next = DListNode(data=data, prev=curr) | |
| def find(self, key): | |
| """ | |
| Search for the first element with `data` matching | |
| `key`. Return the element or `None` if not found. | |
| Takes O(n) time. | |
| """ | |
| curr = self.head | |
| while curr and curr.data != key: | |
| curr = curr.next | |
| return curr # Will be None if not found | |
| def remove_elem(self, node): | |
| """ | |
| Unlink an element from the list. | |
| Takes O(1) time. | |
| """ | |
| if node.prev: | |
| node.prev.next = node.next | |
| if node.next: | |
| node.next.prev = node.prev | |
| if node is self.head: | |
| self.head = node.next | |
| node.prev = None | |
| node.next = None | |
| def remove(self, key): | |
| """ | |
| Remove the first occurrence of `key` in the list. | |
| Takes O(n) time. | |
| """ | |
| elem = self.find(key) | |
| if not elem: | |
| return | |
| self.remove_elem(elem) | |
| def reverse(self): | |
| """ | |
| Reverse the list in-place. | |
| Takes O(n) time. | |
| """ | |
| curr = self.head | |
| prev_node = None | |
| while curr: | |
| prev_node = curr.prev | |
| curr.prev = curr.next | |
| curr.next = prev_node | |
| curr = curr.prev | |
| self.head = prev_node.prev |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment