class ListNode(object):
"""定义一个链表节点类"""
def __init__(self,val =0, next=None):
"""
:param val:节点的值
:param next: 指向下一个节点的指针。当next=None时,表示这个节点是链表的最后一个节点
"""
self.val = val
self.next = next
class LinkList(object):
"""定义一个链表类,该类使用上面定义的ListNode作为节点,通过在链表尾部添加节点来创建链表"""
def __init__(self):
self.head = None
def initList(self,data):
self.head = ListNode(data[0])
p = self.head
for i in data [1:]:
node = ListNode(i)
p.next = node
p = p.next
def reverseList(self):
"""迭代法反转链表"""
prev = None
current = self.head
while current is not None:
next_node = current.next
current.next = prev
prev = current
current = next_node
self.head = prev
def reverseList(self, node):
"""递归法反转链表"""
if node is None or node.next is None:
return node
new_head = self.reverseList(node.next)
node.next.next = node
node.next = None
return new_head
def printList(self):
node = self.head
while node :
print(node.val)
node = node.next
data = [1,2,3]
l = LinkList()
l.initList(data)
l.reverseList()
l.printList()
3
2
1
1.1定义一个链表节点类
首先,我们需要定义一个链表节点类。这个类将包含一个数据字段和一个指向下一个节点的指针字段。这可以通过Python类的定义来实现。以下是链表节点类的定义:
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
在这个类中,val
是节点的值,next
是指向下一个节点的指针。当next=None
时,表示这个节点是链表的最后一个节点。
1.2定义一个链表类
接着,我们再定义一个链表类,该类使用上面定义的ListNode作为节点,通过在链表尾部添加节点来创建链表:
class LinkList(object):
def __init__(self):
self.head = None
def initList(self, data):
self.head = ListNode(data[0])
p = self.head
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
在这个类中,initList
函数接收一个列表data
,并将其转换为链表。head
是链表的头节点,通过遍历data
,创建新的ListNode,并将其添加到链表的末尾。
1.2.1方法__init__()
在Python中,__init__()
是一个特殊的方法,称为类的构造函数或初始化方法。当创建一个类的新实例时,__init__()
方法会自动被调用。这个方法可以用来为新创建的对象设置初始化的状态或值。
在上述的LinkList
类中,__init__()
方法如下:
class LinkList(object):
def __init__(self):
self.head = None
这个__init__()
方法没有输入参数(除了自引用的self
)。在这个方法中,self.head = None
将链表的头部初始化为None
。这意味着当我们创建一个新的LinkList
对象时,它是一个空链表。这是因为在链表中,head
通常用于引用链表的第一个节点。如果head
为None
,那么链表就是空的。
例如,当我们创建一个新的LinkList
对象时:
l = LinkList()
__init__()
方法会自动被调用,将l
这个新创建的链表对象初始化为一个空链表。这是因为在__init__()
方法中,我们设置了self.head = None
,这意味着l
的头部(即第一个节点)是None
,所以l
是一个空链表。
在此之后,我们可以通过调用initList
方法来给这个空链表添加节点,如:
data = [1, 2, 3]
l.initList(data)
这样,l
就变成了一个包含1,2,3的链表。
总的来说,__init__()
方法在这里的作用是创建一个空的链表对象,然后我们可以通过其他方法(如initList
)来给这个空链表添加节点。
1.2.2方法initList()
在LinkList
类中,initList
方法的作用是初始化链表。这个方法接收一个列表data
,并将其转换为链表。
def initList(self, data):
self.head = ListNode(data[0])
p = self.head
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
在这个方法中,首先使用data
的第一个元素创建一个ListNode
对象,并将其赋值给self.head
,这样self.head
就成为了链表的头节点。
然后定义一个指针p
,并将其指向头节点。这个指针将用于遍历链表并添加新的节点。
在for
循环中,遍历data
的剩余元素。对于每个元素,创建一个新的ListNode
对象,并将其添加到链表的末尾。这是通过将p.next
设置为新创建的节点,然后将p
移动到新节点来完成的。
遍历完data
后,链表就创建完成了。self.head
是链表的头节点,通过next
属性可以访问链表中的每个节点。
例如,如果我们有一个列表[1, 2, 3]
,我们可以使用以下代码创建一个链表:
data = [1, 2, 3]
l = LinkList()
l.initList(data)
这样,我们就创建了一个链表,链表中的节点值依次为1,2,3。
1.2.3方法reverseList()
迭代法:
迭代法的核心思想是将每个节点的next
指针改为指向其前一个节点。由于节点没有引用其前一个节点,因此我们必须另存其前一个节点。在更改引用之前,我们还需要另一个指针来存储下一个节点。最后返回新的头引用。
def reverseList(self):
prev = None
current = self.head
while current is not None:
next_node = current.next
current.next = prev
prev = current
current = next_node
self.head = prev
在reverseList
方法中,我们初始化两个指针,prev
和current
。然后我们遍历链表,在每次迭代中,我们将current
的next
指针设置为prev
,然后将prev
和current
都向前移动一个节点。当current
为None
时,表示链表已完全反转,此时prev
就是新的头节点。
递归法:
递归法的思想是首先反转除头节点外的链表,然后再将头节点添加到反转后的链表的尾部。
def reverseList(self, node):
if node is None or node.next is None:
return node
new_head = self.reverseList(node.next)
node.next.next = node
node.next = None
return new_head
在reverseList
方法中,我们首先检查node
是否为None
,或者node
的下一个节点是否为None
。如果是,那么我们返回node
。否则,我们递归地反转除node
外的其余部分,然后将node
添加到反转后的链表的尾部。
1.2.4方法printList()
在LinkList
类中添加一个打印链表的方法。这个方法将遍历链表并打印每个节点的值。
def printList(self):
node = self.head
while node:
print(node.val)
node = node.next