Skip to content

Instantly share code, notes, and snippets.

@CtrlAltCuteness
Created June 26, 2020 22:43
Show Gist options
  • Save CtrlAltCuteness/6e682eed791fa82020a477a649abf4c8 to your computer and use it in GitHub Desktop.
Save CtrlAltCuteness/6e682eed791fa82020a477a649abf4c8 to your computer and use it in GitHub Desktop.
Sample 1-way LinkedList in Python as well as a way to make a copy that is reversed
#!/data/data/com.termux/files/usr/bin/python3
# vim: fileencoding=utf8:filetype=python:syntax=python:nu:ts=2:shiftwidth=2:softtabstop=2:expandtab
# linked_list.py sample program and reversal strategy w/ custom class
# Copyright (C) 2020 ~Katie Heart
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
class Link1Way:
def __init__ (self, value, nextLink=None, /):
self.value = value
self._nextLink = None
if nextLink is not None:
self.nextLink = nextLink
@property
def value (self, /):
return self._value
@value.setter
def value (self, x, /):
self._value = x
def hasNext (self, /):
return self._nextLink is not None
@property
def nextLink (self, /):
if self._nextLink is None:
raise AttributeError() #FIXME
return self._nextLink
@nextLink.setter
def nextLink (self, x, /):
if not isinstance(x, Link1Way):
raise TypeError() #FIXME
self._nextLink = x
@nextLink.deleter
def nextLink (self, /):
if self._nextLink is None:
raise AttributeError() #FIXME
self._nextLink = None
KIND_NORMAL = 0
KIND_LINKS = 1
KIND_LINKED_LIST = 2
class LinkedList1Way:
def __init__ (self, itr=None, /, kind=KIND_NORMAL):
self._firstLink = None
if itr is None:
return
if kind not in (KIND_NORMAL, KIND_LINKS, KIND_LINKED_LIST):
raise ValueError() #FIXME
method = kind == KIND_NORMAL
prev = None
for i in itr:
# convert / validate
if method:
i = Link1Way(i)
elif not isinstance(i, Link1Way):
raise TypeError() #FIXME
else:
i = Link1Way(i.value)
# do action
if prev is None:
self.firstLink = i
else:
prev.nextLink = i
prev = i
def __iter__ (self, /):
return self.iterLinks()
def iterLinks (self, /):
if not self.hasContent():
return
i = self.firstLink
yield i
while i.hasNext():
i = i.nextLink
yield i
def iterValues (self, /):
for i in self.iterLinks():
yield i.value
def hasContent (self, /):
return self._firstLink is not None
@property
def firstLink (self, /):
if self._firstLink is None:
raise AttributeError() #FIXME
return self._firstLink
@firstLink.setter
def firstLink (self, x, /):
if not isinstance(x, Link1Way):
raise TypeError() #FIXME
self._firstLink = x
@firstLink.deleter
def firstLink (self, /):
if self._firstLink is None:
raise AttributeError() #FIXME
self._firstLink = None
#----------
def _output (data, prefix, /):
print(end='{!s}['.format(prefix))
prefix = ''
for i in data:
print(end='{!s} {!r}'.format(prefix, i))
if not prefix:
prefix = ','
print(' ]' if prefix else ']')
def _main ():
# generate
one = tuple( (i + i ** 2) for i in range(10) )
_output(one, 'Source: ')
# make it a linked list (visually verify it is the same)
two = LinkedList1Way(one)
_output(two.iterValues(), 'Verifying LinkedList1Way: ')
# make a reversed one.
three = LinkedList1Way()
for i in two.iterLinks(): # __iter__ uses this but we'll be explicit
i = Link1Way(i.value)
if three.hasContent():
i.nextLink = three.firstLink
three.firstLink = i
# finally ... output the results
_output(three.iterValues(), 'Reversed: ')
if __name__ == '__main__':
_main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment