本文主要介绍链表的python语言实现。
线性表是一种最为基本的数据结构。通常来说,线性表有两种物理存储结构:顺序存储结构和链式存储结构。对Python语言而言,内置list(列表)类型就是一个典型的顺序存储结构,下面主要讨论连式存储结构的Python语言实现。具体代码如下:
# 链表节点类
class LNode:
def __init__(self, elem, next_ = None):
self.elem = elem
self.next = next_
# 双链表节点类
class DLNode(LNode):
def __init__(self, elem, prev = None, next_ = None):
LNode.__init__(self, elem, next_)
self.prev = prev
# 自定义异常
class LinkedListUnderflow(ValueError):
pass
# 链表类
class LList:
# 初始化
def __init__(self):
self._head = None
# 判断是否为空链表
def is_empty(self):
return self._head is None
# 首端插入
def prepend(self, elem):
self._head = LNode(elem, self._head)
# 删除首元素并返回该值
def pop(self):
# 若无节点,则抛出异常
if self._head is None:
raise LinkedListUnderflow("in pop")
e = self._head.elem
self._head = self._head.next
return e
# 在链表的后端插入
def append(self, elem):
if self._head == None:
self._head = LNode(elem)
return
p = self._head
while p.next is not None:
p = p.next
p.next = LNode(elem)
# 删除最后一个元素
def pop_last(self):
if self._head is None:
raise LinkedListUnderflow("in pop_last")
p = self._head
if p.next is None:
e = p.elem
self._head = None
return e
while p.next.next is None:
p = p.next
e = p.next.elem
p.next = None
return e
# 查找元素
def find(self, pred):
p = self._head
while p is not None:
if pred(p.elem):
return p.elem
p = p.next
# 输出链表中的值
def printall(self):
p = self._head
while p is not None:
print(p.elem, end = '')
if p.next is not None:
print(', ', end = '')
p = p.next
print('')
# 链表的遍历
def for_each(self, proc):
p = self._head
while p is not None:
proc(p.elem)
p = p.next
# 迭代器
def elements(self):
p = self._head
while p is not None:
yield p.elem
p = p.next
# 筛选生成器
def filter(self, pred):
p = self._head
while p is not None:
if pred(p.elem):
yield p.elem
p = p.next
# 定义LList子类,增加一个表尾节点引用域
class LList1(LList):
def __init__(self):
LList.__init__(self):
self._rear = None
# 重新定义
def prepend(self, elem):
if self._head is None:
self._head = LNode(elem, self._head)
self._rear = self._head
else:
self._head = LNode(elem, self._head)
def append(self, elem):
if self._head is None:
self._head = LNode(elem, self._head)
self._rear = self._head
else:
self._rear.next = LNode(elem, self._head)
self._rear = self._rear.next
def pop(self):
if self._head is None:
raise LinkedListUnderflow("in pop")
if self._head.next is None:
e = self._head.next.elem
self._head = None
self._rear = self._head
return e
else:
self._head = self._head.next
e = self._head.elem
self._head = self._head.next
return e
def pop_last(self):
if self._head is None:
raise LinkedListUnderflow("in pop_last")
p = self._head
if p.next is None:
e = p.elem
self._head = None
self._rear = self._head
return e
while p.next.next is not None:
p = p.next
e = p.next.elem
self._rear = p
return e
# 循环单链表
class LCList:
def __init__(self):
self._rear = None
def is_empty(self):
return self._rear is None
def prepent(self, elem):
p = LNode(elem)
if self._rear = None:
p.next = p
self._rear = p
else:
p.next = self._rear.next
self._rear.next = p
def append(self, elem):
self.prepent(elem)
self._rear = self._rear.next
def pop(self):
if self._rear is None:
raise LinkedListUnderflow("in pop")
if self._rear.next == self._rear:
self._rear =None
else:
self._rear.next = self._rear.next.next
def printall(self):
if self.is_empty():
return
p = self._rear.next
while True:
print(p.element)
if p == self._rear:
break
p = p.next
# 双链表类
class DLList(LList1):
def __init__(self):
LList1.__init__(self)
def prepend(self, elem):
p = DLList(elem, None, self._head)
if self._head = None:
self._rear = p
else:
p.next.prev = p
self._head = p
def append(self, elem):
p = DLList(elem, self._rear, None)
if self._rear = None:
self._head = p
else:
p.prev.next = p
self._rear = p
def pop(self):
if self._head is None:
raise LinkedListUnderflow("in pop")
e = self._head.elem
self._head = self._head.next
if self._head is not None:
self._head.prev = None
return e
def pop_last(self):
if self._head is None:
raise LinkedListUnderflow("in pop_last")
e = self._rear.elem
self._rear = self._rear.prev
if self._rear is not None:
self._rear.next = None
return e