我目前正在学习在线计算机科学入门课程,刚刚学习了链表的概念。虽然我理解链表的概念,但我仍然不确定如何处理链表。
因此,我寻求帮助来解决以下问题,这将对我理解链表有很大帮助:
编写一个函数(不在 LinkedList 类定义中(,给定一个链表,将更改该链表以过滤掉奇数。函数返回后,链表将只有偶数。
我不确定如何访问列表中的节点并检查它们是奇数还是偶数,并相应地删除或保留它们。
如果这似乎是一个微不足道的问题,我深表歉意,但我希望任何可以帮助我学习的帮助。
链表和节点类的代码(由在线课程提供(:
class Node:
def __init__(self, data=None, next_node=None):
self.data = data
self.next = next_node
def __str__(self):
return str(self.data)
class LinkedList:
def __init__(self):
self.length = 0
self.head = None
def print_list(self):
node = self.head
while node is not None:
print(node, end=' ')
node = node.next
print('')
def add_at_head(self, node):
node.next = self.head
self.head = node
self.length += 1
def remove_node_after(self, node):
if node.next is not None:
temp = node.next
node.next = node.next.next
temp.next = None
self.length -= 1
def remove_first_node(self):
if self.head is None:
return
temp = self.head
self.head = self.head.next
temp.next = None
self.length -= 1
def print_backward(self):
def print_nodes_backward(node):
if node.next is not None:
print_nodes_backward(node.next)
if node is not None:
print(node, end=' ')
if self.head is not None:
print_nodes_backward(self.head)
print('')
假设你有一个基本的简单链表,看起来像这样:
class LinkedList:
class ListNode:
def __init__(self, data):
self.data = data
self.next = None
def __init__(self):
self.head = None
def add(self, data):
if self.head is None:
self.head = LinkedList.ListNode(data)
else:
current_node = self.head
while current_node.next is not None:
current_node = current_node.next
current_node.next = LinkedList.ListNode(data)
def __str__(self):
ret = "["
current_node = self.head
while current_node is not None:
ret = ret + str(current_node.data)
if current_node.next is not None:
ret = ret + ", "
current_node = current_node.next
ret = ret + "]"
return ret
换句话说,LinkedList
包含一个head
,即ListNode
。链表中的每个元素都包含在一个ListNode
中,每个ListNode
都指向列表中的下一个元素。
如您所见,为了向列表中添加元素,如果列表为空(即self.head is None
(,或者我们通过从head
开始,通过连续跳转到每个ListNode
的.next
元素来遍历到列表的末尾。我们还使用此范例来打印列表的字符串表示形式。
因此,要从链表中删除任何节点,我们可以简单地更改引用它的节点,以便跳过我们要删除的节点。在这一点上,它将消失。
要删除所有包含奇数数据的列表节点,我们可以执行以下操作:
def remove_odds(self):
# special case: head node
# remove odd head elements by simply setting head to the next element after
while (self.head is not None) and (self.head.data % 2 == 1):
self.head = self.head.next
# regular case: the rest of the nodes
current_node = self.head
while (current_node is not None) and (current_node.next is not None):
# if the next node's data is odd, then
if current_node.next.data % 2 == 1:
# skip that node by pointing this node's .next to the next node's .next
current_node.next = current_node.next.next
# otherwise, move forwards in the list
else:
current_node = current_node.next
概念验证:
>>> lst = LinkedList()
>>> lst.add(2)
>>> lst.add(5)
>>> lst.add(6)
>>> lst.add(3)
>>> lst.add(7)
>>> lst.add(8)
>>> lst.add(10)
>>> lst.add(1)
>>> lst.add(4)
>>> print(lst)
[2, 5, 6, 3, 7, 8, 10, 1, 4]
>>> lst.remove_odds()
>>> print(lst)
[2, 6, 8, 10, 4]
从注释中复制: 这个想法是在记住前一个节点的同时从头到尾遍历列表; 当你找到一个垃圾节点时,将remove_node_after
应用于记住的节点,或者如果我们还没有时间记住任何东西,则将头部移动到当前节点。
代码将是这样的(未经测试(:
class LinkedList:
# ...
def delete_if(self, pred):
prev = None
curr = self.head
while curr:
if pred(curr.data):
if prev:
self.remove_node_after(prev)
else:
self.head = curr
prev = curr
curr = curr.next
llist.delete_if(lambda x: x % 2 == 1) # delete if odd
# Mahmoud AL-Mokdad
# this course on Udemy By SEfactoru right😁
# use my code 😉
def filter_even(ll):
first_node = ll.head
while (first_node is not None) and (first_node.data % 2 != 0):
ll.remove_first_node()
first_node = ll.head
node = first_node
while node is not None and node.next is not None:
if node.next.data % 2 != 0:
ll.remove_node_after(node)
else:
node = node.next