链表结构是最常用的数据结构,和数组一样,链表结构是一个具体的数据类型,它实现了很多类型的集合,包括列表。链表结构的两种最简单的结构是单链表结构和双链表结构。
图1显示了两种类型的链表结构。
1.单链表的Python实现
首先定义一个单链表节点类`
class Node(object):
def __init__(self,value=None,next=None):
self.value = value
self.next = next
接着定义一个单链表结构类
class LinkedList(object):
def __init__(self):#初始化链表的头节点以及链表的长度
self.head = Node()
self.length = 0
def __len__(self):#返回链表的长度
return self.length
1.在链表末尾插入节点
def append(self,value):#添加节点,从末尾处添加
node = Node(value)
if self.length==0:
self.head.next=node
self.length += 1
else:
curnode = self.head.next
while curnode.next!=None:
curnode = curnode.next
curnode.next=node
self.length += 1
测试:
l=LinkedList()
l.append(3)
l.append(5)
l.append(9)
print('链表长度:',len(l))
i=1
for node in l:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
链表长度: 3
第1个链表节点的值:3
第2个链表节点的值:5
第3个链表节点的值:9
2.在链表开始出插入节点
def start_insert(self,insert_value):#在开始出插入
node = Node(insert_value)
if self.length==0:
self.head.next = node
else:
tmp_node=self.head.next
self.head.next = node
node.next = tmp_node
self.length +=1
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('链表长度:',len(l))
i=1
for node in l:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
链表长度: 4
第1个链表节点的值:10
第2个链表节点的值:9
第3个链表节点的值:5
第4个链表节点的值:3
3.在链表任意位置插入节点
def insert(self,location,value):#在任意位置插入节点
node = Node(value)
if self.length==0:
self.head.next = node
self.length += 1#插入一个节点,链表长度加1
else:
for nd in self.iter_node():
if nd.value == location:
tmp_node = nd.next
nd.next = node
node.next = tmp_node
self.length += 1
return True
return False#返回False,未找到插入位置
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('插入之前链表长度:',len(l))
i=1
print('遍历链表:')
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
l.insert(3,100)#在末尾插入
l.insert(10,200)#在开始处插入
l.insert(5,300)#在任意位置插入节点
l.insert(200,2000)#在node.value==200处插入一个node.value=2000的节点
print('插入之后链表长度:',len(l))
print('遍历链表:')
i=1
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
插入之前链表长度: 4
遍历链表:
第1个链表节点的值:10
第2个链表节点的值:9
第3个链表节点的值:5
第4个链表节点的值:3
插入之后链表长度: 8
遍历链表:
第1个链表节点的值:10
第2个链表节点的值:200
第3个链表节点的值:2000
第4个链表节点的值:9
第5个链表节点的值:5
第6个链表节点的值:300
第7个链表节点的值:3
第8个链表节点的值:100
4.遍历链表
def __iter__(self):#遍历链表节点
for node in self.iter_node():
yield node.value
def iter_node(self):
curnode = self.head.next
while curnode.next !=None:
yield curnode
curnode = curnode.next
if curnode.next == None:
yield curnode
5.搜索节点,按照value搜索
def search(self,value):#搜索节点
index = 1
if self.length==0:#如果长度为0,则表示链表结构中只有一个头节点
return -1#返回-1,表示不存在该节点
else:
for node in self.iter_node():
if node.value == value:
return index #搜索到节点的序号
index += 1
return -1#未搜索到节点
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
print('遍历链表:')
i=1
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
print('value_3 index:',l.search(3))#输出搜索到的节点的序号
print('value_5 index:',l.search(5))
print('value_10 index:',l.search(10))
print('value_100 index:',l.search(100))#若未搜索到目标性,则返回-1
输出:
遍历链表:
第1个链表节点的值:10
第2个链表节点的值:9
第3个链表节点的值:5
第4个链表节点的值:3
value_3 index: 4
value_5 index: 3
value_10 index: 1
value_100 index: -1
6.替换节点,按照value替换
def replace(self,old_value,new_value):#替换操作
index = 0
if self.length==0:
return False#如果长度等于0,返回False
else:
for node in self.iter_node():
if node.value == old_value:
node.value=new_value
index += 1
if index!=0:
return index#替换节点数
else:
return False #替换的目标项不存在
测试:
l=LinkedList()
l.start_insert(3)
l.start_insert(5)
l.start_insert(9)
l.start_insert(10)
l.start_insert(10)
l.start_insert(5)
l.start_insert(5)
print('遍历链表:')
i=1
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
print('替换的节点数量:',l.replace(3,300))#把节点的值3替换成300,按照值替换,并非按照序号替换
print('替换的节点数量:',l.replace(5,500))#替换成功,返回替换的节点数量
print('替换的节点数量:',l.replace(9,900))
print('替换的节点数量:',l.replace(10,1000))
print('遍历链表:')
i=1
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
遍历链表:
第1个链表节点的值:5
第2个链表节点的值:5
第3个链表节点的值:10
第4个链表节点的值:10
第5个链表节点的值:9
第6个链表节点的值:5
第7个链表节点的值:3
替换的节点数量: 1
替换的节点数量: 3
替换的节点数量: 1
替换的节点数量: 2
遍历链表:
第1个链表节点的值:500
第2个链表节点的值:500
第3个链表节点的值:1000
第4个链表节点的值:1000
第5个链表节点的值:900
第6个链表节点的值:500
第7个链表节点的值:300
7.删除节点,在任意位置删除
def del_node(self,del_value):#删除节点
Flag = False
if self.length==0:
return Flag
else:
previous_node = self.head
for curnode in self.iter_node():
if curnode.value == del_value:
previous_node.next=curnode.next
del curnode
self.length -= 1
Flag = True
else:
previous_node = curnode
return Flag
def output(l):
print('遍历链表:')
i=1
for node in l:
print(' 第%d个链表节点的值:%d'%(i,node))
i += 1
测试:
l=LinkedList()
l.append(3)
l.append(5)
l.append(9)
l.append(10)
l.append(10)
l.append(5)
l.append(5)
l.append(11)
output(l)
print('删除节点值为3的节点:',l.del_node(3))#返回True,表示删除成功,否则返回False
output(l)
print('删除节点值为5的节点:',l.del_node(5))
output(l)
print('删除节点值为9的节点:',l.del_node(9))
output(l)
print('删除节点值为11的节点:',l.del_node(11))
output(l)
输出:
遍历链表:
第1个链表节点的值:3
第2个链表节点的值:5
第3个链表节点的值:9
第4个链表节点的值:10
第5个链表节点的值:10
第6个链表节点的值:5
第7个链表节点的值:5
第8个链表节点的值:11
删除节点值为3的节点: True
遍历链表:
第1个链表节点的值:5
第2个链表节点的值:9
第3个链表节点的值:10
第4个链表节点的值:10
第5个链表节点的值:5
第6个链表节点的值:5
第7个链表节点的值:11
删除节点值为5的节点: True
遍历链表:
第1个链表节点的值:9
第2个链表节点的值:10
第3个链表节点的值:10
第4个链表节点的值:11
删除节点值为9的节点: True
遍历链表:
第1个链表节点的值:10
第2个链表节点的值:10
第3个链表节点的值:11
删除节点值为11的节点: True
遍历链表:
第1个链表节点的值:10
第2个链表节点的值:10
2.双链表的Python实现
1.添加节点,从末尾添加
class Node(object):
def __init__(self,value=None,prev=None,next=None):
self.value = value
self.prev = prev
self.next = next
class Double_LinkedList(object):
def __init__(self):#初始化双链表只有一个头结点,它的前向指针和后向指针都指向自己,长度为0
node = Node()
node.prev = node
node.next = node
self.head = node
self.length = 0
def __len__(self):
return self.length
def headnode(self):#获取第一个节点
return self.head.next
def tailnode(self):#获取最后一个节点
return self.head.prev
def append(self,value):#添加节点,从末尾添加
node = Node(value)
tail_node = self.tailnode()
tail_node.next = node
node.prev = tail_node
node.next = self.head
self.head.prev = node
self.length += 1
测试:
DL = Double_LinkedList()
DL.append(1)
DL.append(2)
DL.append(3)
DL.append(3)
DL.append(2)
DL.append(1)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
双链表的长度为: 6
第1个链表节点的值:1
第2个链表节点的值:2
第3个链表节点的值:3
第4个链表节点的值:3
第5个链表节点的值:2
第6个链表节点的值:1
2.在开头添加节点
def head_append(self,value):
node =Node(value)
if self.head.next is self.head:
node.next = self.head
node.prev = self.head
self.head.next = node
self.head.prev = node
else:
node.prev = self.head
head_node = self.headnode()
self.head.next = node
head_node.prev = node
node.next = head_node
self.length += 1
测试:
DL = Double_LinkedList()
DL.head_append(1)
DL.head_append(2)
DL.head_append(3)
DL.head_append(6)
DL.head_append(7)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
双链表的长度为: 5
第1个链表节点的值:7
第2个链表节点的值:6
第3个链表节点的值:3
第4个链表节点的值:2
第5个链表节点的值:1
3.在任意位置添加节点
def insert(self,index,value):#在任意位置插入新节点
node = Node(value)
i = 1
if self.length<index:
raise Exception('out of range')
if self.head.next is self.head:
self.head.next = node
self.head.prev = node
node.next = self.head
node.prev = self.head
self.length += 1
return True
else:
if index==0:
self.head_append(value)
return True
for cur_node in self.iter_node():
if i == index:
next_node = cur_node.next
node.prev = cur_node
node.next = next_node
cur_node.next = node
next_node.prev = node
self.length += 1
return True
i += 1
测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(0,11)#在位置0处插入一个节点值为11的新节点
DL.insert(2,22)#在位置2处插入一个节点值为22的新节点
DL.insert(5,55)#在位置5处插入一个节点值为55的新节点
print('双链表的长度为:',DL.length)
i=1
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
双链表的长度为: 6
第1个链表节点的值:11
第2个链表节点的值:2
第3个链表节点的值:22
第4个链表节点的值:3
第5个链表节点的值:4
第6个链表节点的值:55
4.删除节点
def del_node(self,index):#删除节点
i=1
for cur_node in self.iter_node():
if i == index:
next_node=cur_node.next
prev_node=cur_node.prev
prev_node.next = next_node
next_node.prev = prev_node
self.length -= 1
return True
i += 1
测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(1,8)#在位置2处插入一个节点值为4的新节点
print('双链表的长度为:',DL.length)
i=1
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
print('开始删除。。。。。。')
DL.del_node(1)
DL.del_node(3)
print('双链表的长度为:',DL.length)
i=1
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
输出:
双链表的长度为: 4
第1个链表节点的值:2
第2个链表节点的值:8
第3个链表节点的值:3
第4个链表节点的值:4
开始删除。。。。。。
双链表的长度为: 2
第1个链表节点的值:8
第2个链表节点的值:3
5.遍历输出节点
def iter_node(self):#遍历节点
if self.head.next is self.head:
return -1
cur_node = self.head.next
while cur_node.next is not self.head:
yield cur_node
cur_node = cur_node.next
yield cur_node
def __iter__(self):#遍历节点,输出每个节点的值
for node in self.iter_node():
yield node.value
def reverse_iter_node(self):#反向遍历节点
if self.head.prev is self.head:
return False
cur_node = self.head.prev
while cur_node.prev is not self.head:
yield cur_node
cur_node = cur_node.prev
yield cur_node
测试:
DL = Double_LinkedList()
DL.insert(0,2)#在位置0处插入一个节点值为2的新节点
DL.insert(1,3)#在位置1处插入一个节点值为3的新节点
DL.insert(2,4)#在位置2处插入一个节点值为4的新节点
DL.insert(1,8)#在位置2处插入一个节点值为4的新节点
print('双链表的长度为:',DL.length)
i=1
print('正向遍历节点:')
for node in DL:
print('第%d个链表节点的值:%d'%(i,node))
i += 1
print('反向遍历节点:')
print([node.value for node in DL.reverse_iter_node()])
输出:
双链表的长度为: 4
正向遍历节点:
第1个链表节点的值:2
第2个链表节点的值:8
第3个链表节点的值:3
第4个链表节点的值:4
反向遍历节点:
[4, 3, 8, 2]