Python中实现单链表
关于链表
链表是一种将元素存放在通过连接构造出来的一系列存储块中的结构。
链表的结构由两部分组成:数据区(存储数据)+链接区(存储地址),这样的结构称为一个节点,如图所示:
下面是一个单链表的例子:
箭头显示了单个链接列表中的节点是如何组合在一起的。
链表的实现
节点结构的定义
前面说过,链表每一个节点是由两部分组成的数据区+链接区,因此在定义时需要表示出来。
class Node(object):
"""定义一个节点类"""
def __init__(self,val):
self.val = val
self.next = None
单链表实现
在单链表中我们通常会指定一个头结点(head),head指向链表中的第一个元素节点,方便我们进行链表的遍历、元素查找等,也就是说知道了头节点也就知道了整个链表。
单链表的实现代码如下:
我们首先定义了一个头结点
class SingleLinkList(object):
def __init__(self,node=None):
self.__head = node
我们接着定义了链表中的操作方法
1.链表判断是否为空
def is_empty(self):
"""链表是否为空"""
return self.__head == None
通过判断头结点的指向,来判断链表是否为空。
2.链表的长度
def length(self):
"""链表的长度"""
# 定义一个指针,用来移动遍历节点
cur = self.__head
# count用来记录节点数量
count = 0
while(cur != None):
count += 1
cur = cur.next
return count
3.链表的遍历
def travel(self):
cur = self.__head
while(cur!=None):
print(cur.val," ")
cur=cur.next
4.链表元素的添加
链表尾部添加元素,尾插法
def append(self,val):
"""链表尾部添加元素"""
node = Node(val)
# 链表为空时
if self.__head == None:
self.__head = node
else:
cur = self.__head
while(cur.next != None):
cur = cur.next
cur.next = node
链表头部添加元素,头插法
def add(self,val):
"""链表头部添加元素,头插法"""
node = Node(val)
node.next = self.__head
self.__head = node
图解步骤:
注:这里需要注意在插入新的节点时,我们要先将新的节点指向第一个节点,在将头节点指向新节点,保证原有的节点不会丢失。
指定位置添加元素
def insert(self,pos,val):
"""指定位置添加元素"""
# 下标小于0时,相当于在头部插入
if pos < 0:
self.add(val)
# 下标超过链表的长度,相当于在尾部插入
elif pos > ( self.length()-1):
self.append(val)
else:
pre = self.__head
count = 0
while(count < pos -1):
pre = pre.next
count += 1
node = Node(val)
node.next = pre.next
pre.next = node
图解步骤:
5.链表节点的删除
def remove(self,val):
"""删除节点,双指针"""
pre = None
cur = self.__head
while(cur != None):
if cur.val == val:
# 判断此节点是否是头结点
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
图解步骤:
完整代码:
class Node(object):
"""定义一个节点类"""
def __init__(self,val):
self.val = val
self.next = None
class SingleLinkList(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
"""链表是否为空"""
return self.__head == None
def length(self):
"""链表的长度"""
cur = self.__head
# count记录数量
count = 0
while(cur != None):
count += 1
cur = cur.next
return count
def travel(self):
cur = self.__head
while(cur!=None):
print(cur.val,end = " ")
cur=cur.next
print("")
def append(self,val):
"""链表尾部添加元素"""
node = Node(val)
if self.__head == None:
self.__head = node
else:
cur = self.__head
while(cur.next != None):
cur = cur.next
cur.next = node
def add(self,val):
"""链表头部添加元素,头插法"""
node = Node(val)
# print(node.val)
node.next = self.__head
self.__head = node
def insert(self,pos,val):
"""指定位置添加元素"""
if pos < 0:
self.add(val)
elif pos > ( self.length()-1):
self.append(val)
else:
pre = self.__head
count = 0
while(count < pos -1):
pre = pre.next
count += 1
# 当循环退出后,pre指向pos-1的位置
node = Node(val)
node.next = pre.next
pre.next = node
def remove(self,val):
"""删除节点,双指针"""
pre = None
cur = self.__head
while(cur != None):
if cur.val == val:
# 判断此节点是否是头结点
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
l = SingleLinkList()
l.append(10)
l.append(20)
l.travel()
l.add(30)
l.travel()
l.insert(1,40)
l.travel()
l.remove(30)
l.travel()
"""
上述代码执行的结果:
10 20
30 10 20
30 40 10 20
40 10 20
"""
总结
我们给出一下链表的各种操作的时间复杂度: