首先我们来实现最简单的单向链表,单项链表的创建有两种方法,头插法和尾插法,这里我们使用尾插法来实现单向链表:
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
self.length = 0
def append(self,data):
node = Node(data)
if self.head != None:
p = self.head
while p.next != None:
p = p.next
p.next = node
else:
self.head = node
self.length+=1
def Bianli(self):
lst = []
node = self.head
while node != None:
lst.append(node.data)
node = node.next
return lst
lin = LinkedList()
for i in range(10):
lin.append(i)
print(lin.Bianli())
print(lin.length)
上边的部分实现了一个链表结构,可以进行对数据的存入以及遍历。
下面我们来实现对单链表的查询与添加和删除操作:
def getdata(self,ud):
if ud>=self.length:
ud = self.length-1
elif ud<0:
ud = 0
p = self.head
n = 0
while n<ud:
p = p.next
n += 1
return p.data
def insdata(self,data,ud): #插入数据,需要传入的参数有数据与下标
node = Node(data)
if ud>=self.length:
ud = self.length-1
elif ud<0:
ud = 0
if ud>0:
p = self.head
n = 0
while n<(ud-1):
p = p.next
n += 1
node.next = p.next
p.next = node
else:
node.next = self.head
self.head = node
self.length += 1
def deldata(self,ud):
if ud>=self.length:
ud = self.length-1
elif ud<0:
ud = 0
if ud>0:
p = self.head
n = 0
while n<(ud-1):
p = p.next
n += 1
node = p.next #找到待删除节点
p.next = node.next
node.next = None
else:
node = self.head
self.head = node.next
node.next = None
self.length-=1
return node.data #返回删除的节点值
到此我们实现了单链表的建立与查询、添加与删除操作。下面来试着进行一些更加高阶的操作:
如何从尾到头打印一个单向链表?
反向打印单向链表时,我们第一个想到的是新建一个容器,比如栈,将链表中的数据取出,然后存入栈中,最后打印栈即可。这里提供另一种思路,递归调用的方法,也就是说,如果要打印链表中的一个值,你要先打印它后边的值:
def pri(node):
if node.next != None:
pri(node.next)
print(node.data)
lin = LinkedList()
for i in range(10):
lin.append(i)
node = lin.head
pri(node)
那么如何将一个单向链表反转呢?我的建议是直接按照头插法的方式建表。当然,要实现这个目标也可以使用递归,找到一个节点,让这个节点的下一个节点的next指向自己,同时,在下一个节点的next指针发生变化之前,先递归调用下一个节点的反转,这样会递归到尾节点,直到尾节点反转指针之后,前一个节点才可以执行反转操作。
def rev(self):
def reversal(node):
if node.next != None:
nextNode = node.next
reversal(nextNode)
nextNode.next = node
else:
self.head.next = None
self.head = node
reversal(self.head)