定义一个链表在c++中需要创建一个结构体,结构体包含一个指针域和一个数据域,数据域很简单,可以是数字、字母、字符串等,指针域代表指针,用来指向链表的下一个节点.对于c++来说,链表的操作需要调用指针,是相当麻烦的,而python不需要,只需要一个简单的赋值操作就可以,例如:a = listNode.next.
链表的基本操作有以下几个方面:
下面就写一下链表的创建以及常见的操作,
首先是创建一个空链表:
class Node(object):
def __init__(self, value = None, next = None):
self.value = value
self.next = next
def __str__(self):#定义这个魔法函数,主要是为了debug,方便调试
return('<Node: value: {}, next={}>'.format(self.value, self.next))
a = Node()
print(a)
<Node: value: None, next=None>
创建一个单链表,并实现一些链表操作
class LinkedList(object):
[root] -> [node0] -> [node1] -> [node2]
"""
def __init__(self, maxsize=None):
"""
:param maxsize: int or None, 如果是 None,无限扩充
"""
self.maxsize = maxsize
self.root = Node() # 默认 root 节点指向 None
self.tailnode = None
self.length = 0
def __len__(self):## 创建魔法函数,返回链表的长度
return self.length
def append(self, value): # O(1)
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value) # 构造节点
tailnode = self.tailnode#创建尾节点,指向none
if tailnode is None: # 还没有 append 过,length = 0, 追加到 root 后
self.root.next = node
else: # 否则追加到最后一个节点的后边,并更新最后一个节点是 append 的节点
tailnode.next = node
self.tailnode = node
self.length += 1
def appendleft(self, value):
if self.maxsize is not None and len(self) >= self.maxsize:
raise Exception('LinkedList is Full')
node = Node(value)
if self.tailnode is None: # 如果原链表为空,插入第一个元素需要设置 tailnode
self.tailnode = node
headnode = self.root.next
self.root.next = node
node.next = headnode
self.length += 1
def __iter__(self):
for node in self.iter_node():
yield node.value
def iter_node(self):
"""遍历 从 head 节点到 tail 节点"""
curnode = self.root.next
while curnode is not self.tailnode: # 从第一个节点开始遍历
yield curnode
curnode = curnode.next # 移动到下一个节点
if curnode is not None:
yield curnode
def remove(self, value): # O(n)
""" 删除包含值的一个节点,将其前一个节点的 next 指向被查询节点的下一个即可
:param value:
"""
prevnode = self.root #
for curnode in self.iter_node():
if curnode.value == value:
prevnode.next = curnode.next
if curnode is self.tailnode: # NOTE: 注意更新 tailnode
if prevnode is self.root:
self.tailnode = None
else:
self.tailnode = prevnode
del curnode
self.length -= 1
return 1 # 表明删除成功
else:
prevnode = curnode
return -1 # 表明删除失败
def find(self, value): # O(n)
""" 查找一个节点,返回序号,从 0 开始
:param value:
"""
index = 0
for node in self.iter_node(): # 我们定义了 __iter__,这里就可以用 for 遍历它了
if node.value == value:
return index
index += 1
return -1 # 没找到
def popleft(self): # O(1)
""" 删除第一个链表节点
"""
if self.root.next is None:
raise Exception('pop from empty LinkedList')
headnode = self.root.next
self.root.next = headnode.next
self.length -= 1
value = headnode.value
if self.tailnode is headnode: # 勘误:增加单节点删除 tailnode 处理
self.tailnode = None
del headnode
return value
def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
self.tailnode = None
def reverse(self):
"""反转链表"""
curnode = self.root.next
self.tailnode = curnode # 记得更新 tailnode,多了这个属性处理起来经常忘记
prevnode = None
while curnode:
nextnode = curnode.next
curnode.next = prevnode
if nextnode is None:
self.root.next = curnode
prevnode = curnode
curnode = nextnode