Created
March 23, 2013 13:28
-
-
Save cabiad/5227738 to your computer and use it in GitHub Desktop.
A linked list implementation in Python2 with support for Python-style iteration and a surprisingly elegant (though simple) implementation of Floyd's cycle finding algorithm.
This file contains 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
######################################################### | |
# # | |
# Copyright 2013 Christopher Abiad All rights reserved. # | |
# # | |
######################################################### | |
__author__ = 'Chris Abiad <chris@chrisabiad.com>' | |
import collections | |
class LinkedList(collections.Iterable): | |
"""docstring for LinkedList""" | |
class Node(object): | |
"""docstring for Node""" | |
def __init__(self, data, next=None): | |
super(LinkedList.Node, self).__init__() | |
self.data = data | |
self.next = next | |
class LinkedListIterator(collections.Iterator): | |
"""An in-sequence linked list iterator""" | |
def __init__(self, head): | |
"""docstring for __init__""" | |
self._cur = head | |
def __iter__(self): | |
"""Part of the Iterator protocol""" | |
return self | |
def next(self): | |
"""Part of the Iterator protocol""" | |
if self._cur is None: | |
raise StopIteration | |
retval = self._cur | |
self._cur = self._cur.next | |
return retval | |
def __init__(self): | |
super(LinkedList, self).__init__() | |
self.head = None | |
def __iter__(self): | |
it = LinkedList.LinkedListIterator(self.head) | |
return iter(it) | |
def add(self, data): | |
"""add new node to head of list""" | |
new = LinkedList.Node(data, self.head) | |
self.head = new | |
return new | |
def add_node(self, node): | |
"""docstring for add_node""" | |
node.next = self.head | |
self.head = node | |
return node | |
def rm(self, node): | |
"""del node from list | |
Singly linked list, so O(n)""" | |
it = iter(self) | |
prev = self.head | |
try: | |
while True: | |
n = it.next() | |
if n is node: | |
# Handle item as head of list specially | |
if n is self.head: | |
self.head = self.head.next | |
else: | |
prev.next = n.next | |
return | |
prev = n | |
except StopIteration: | |
raise KeyError | |
def has_loop(self): | |
class Skip2Iterator(LinkedList.LinkedListIterator): | |
def next(self): | |
super(Skip2Iterator, self).next() | |
return super(Skip2Iterator, self).next() | |
it = LinkedList.LinkedListIterator(self.head) | |
it2 = Skip2Iterator(self.head) | |
try: | |
while True: | |
n1 = it.next() | |
n2 = it2.next() | |
if n1 is n2: | |
return True | |
except StopIteration: | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment