版权声明:本文为博主原创文章,未经博主允许可以转载。 https://blog.csdn.net/killeri/article/details/82851748
一个普通的单链表(一个指针域),对于其最重要的就是单链表的头指针,通过头指针可以确定单链表的一些属性,如:是不是空的,通过头指针进行遍历等。
我们用python做一个单链表的类实现,要求可以建立一个空的单链表,还要能够实现一些单链表的基本操作,如判断是不是空的,头部尾部插入,删除,遍历等
首先就是定于一个链表节点的类:
class LNode:
def __init(self, elem, next = None):
self.elem = elem
self.next_ = next
# 定义一个空的错误类,必须继承自基础的错误类
class LListValueError(ValueError):
pass
接下来建立链表的类:
class LList:
def __init__(self):
self._head = None
# 那么初始化链表类就是建立了一个空链表
# 首先是一个判断空的方法
def is_empty(self):
return self._head == None
# 接下来用于在头部插入一个节点
def prepend(self, elem):
self._head = LNode(elem, self._head)
# 这是最简单的实现方法
# 一个头部删除的方法
# 注意删除,我们不能删除一个空链表,那么就需要使用定义的错误类
def pop_first(self):
if not self._head:
raise LListValueError(“wrong”)
e = self._head.elem
self._head = self._head.next
return e
# 直接将头指针指向下一个节点,抛弃原头节点,python会自动回收
# 其储存空间的
# 接下来是尾部插入
def append(self, elem):
p = self._head
while p:
if not p.next_:
p.next_ = LNode(elem)
return
p = p.next
self._head = LNode(elem)
# 这里有两种情况,一种是空表,这是直接等于就可以了
# 其他的遍历到最后一个元素,然后将他的next指针指向这个新建的元素
# 这里有个变量p,我们称之为扫描指针。
# 对于尾部删除,有三种情况:空表,一个元素,两个及以上的元素
def pop_last(self):
if not self._head:
raise LListValueError("wrong")
if not self._head.next:
self._head = None
p = self._head
while p.next.next:
p = p.next
e = p.next.elem
p.next = None
return e
# 最后关于表的遍历问题,我们对于表的遍历问题
# 对于这种汇集对象来说,对其中的各个对象进行一些操作是很常见的,
# 我们除了可以从头指针顺着找下去之外,还有一些是对特定元素进行的操作
# 主要实现后者
def for_each(self, operate):
p = self._head
while p:
operate(p.elem)
p = p.next
# 其实还有一个就是关于python迭代器的,python的主要迭代工具就是迭代器
# 用yield关键字生成一个生成器函数是一个很好的选择
def elements(self):
p = self._head
while p:
yield p.elem
p = p.next
这就是一个链表类的实现。
如果深入理解链表的实现的话,可以看出self._head是头节点,但不是第一个节点,它本身是一个只包含指针域的链表对象,而这个指针就是指向链表的第一个节点。
对于更复杂的链表对象来说,我们还可以存储链表的长度,链表的尾指针等,这就需要为链表对象设计一个数据结构(一个类)
包含链表长度的话:
class listObject:
def __init__(self, next_ = None):
self.listLen = LNode.node_num
self.head = next_
至于这个链表长度哪里来,为节点类添加一个类属性,用于计数,新的节点类如下:
class newLNode:
node_num = 0
def __init__(self, elem, next_ = None):
self.elem = elem
self.next = next_
newLNode.node_num += 1
# 这样每初始化一个新的节点,就可以多增加一个点的计数,当然删除节点的话,还需要手动来!
还有循环链表,双向链表等,见下一章!!!!
参考《数据结构与算法 python语言的实现》,强推这本书!!!