我已经找到了解决方案...感谢您的帮助!
答案 0 :(得分:1)
问题在intersection()方法中,您在其中重新初始化current_node3。 以下是针对此问题的解决方法
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def sortedinsert(self, data):
current_node = self.head
if current_node==None:
new_node = Node(data)
self.head = new_node
return
if current_node.data > data:
new_node = Node(data)
new_node.next = current_node
self.head = new_node
return
while current_node.next is not None:
if current_node.next.data > data:
break
current_node = current_node.next
new_node = Node(data)
new_node.next = current_node.next
current_node.next = new_node
return
def delete(self, item):
current_node = self.head
if current_node and current_node.data == item:
self.head = current_node.next
current_node = None
return
previous_node = None
while current_node and current_node.data != item:
previous_node = current_node
current_node = current_node.next
if current_node is None:
return
previous_node.next = current_node.next
current_node = None
def deletebefore(self, value):
current_node = self.head
previous_node = None
if current_node.data == value:
print("There is no previous character")
return
while current_node.next.data != value:
previous_node = current_node
current_node = current_node.next
if current_node.next == None:
print("Given character not found")
return
if previous_node == None and current_node.next.data == value:
self.head = current_node.next
current_node = None
return
if current_node.next.data == value and previous_node:
previous_node.next = current_node.next
current_node = None
def update(self, prev_value, new_value):
new_value=Node(new_value)
current_node = self.head
while current_node.data != prev_value:
current_node = current_node.next
if current_node.data == prev_value:
current_node.data = new_value.data
return
def isempty(self,l1,l2,l3):
current_node = self.head
if current_node is None:
print("List is empty")
else:
print("List is not Empty")
def getsize(self):
items = []
present_node = self.head
while present_node is not None:
items.append(present_node.data)
present_node = present_node.next
print(len(items))
def getfirst(self):
current_node = self.head
if current_node:
print(current_node.data)
def intersection(self,l1,l2):
if l1==None and l2==None:
print("Linked lists are empty")
current_node = l1.head
current_node2 = l2.head
current_node3=self.head
while current_node2!=None:
if current_node2.data==current_node.data:
if current_node3 is None:
current_node3=current_node2 # Here is the problem. You are reinitializint the node. So, it no more points to head node
self.head = current_node2 # Fix : set head to node 3 again
if current_node2.next==None:
return
else:
current_node2=current_node2.next
current_node=current_node.next
else:
while current_node3!=None:
current_node3=current_node3.next
current_node3=current_node2
current_node2=current_node2.next
current_node=current_node.next
else:
current_node=current_node.next
if current_node==None:
current_node=l1.head
current_node2=current_node2.next
def display(self):
current_node=self.head
while current_node!=None:
print(current_node.data)
current_node=current_node.next
def main():
l1 = LinkedList()
l2 = LinkedList()
l3 = LinkedList()
l1.sortedinsert(19)
l1.sortedinsert(16)
l2.sortedinsert(19)
l2.sortedinsert(15)
l2.sortedinsert(16)
l3.intersection(l1,l2)
def intersection(self,l1,l2):
if l1==None and l2==None:
print("Linked lists are empty")
current_node = l1.head
current_node2 = l2.head
current_node3=self.head
while current_node2!=None:
if current_node2.data==current_node.data:
if current_node3 is None:
current_node3=current_node2
if current_node2.next==None:
return
else:
current_node2=current_node2.next
current_node=current_node.next
else:
while current_node3!=None:
current_node3=current_node3.next
current_node3=current_node2
current_node2=current_node2.next
current_node=current_node.next
else:
current_node=current_node.next
if current_node==None:
current_node=l1.head
current_node2=current_node2.next
def main():
l1 = LinkedList()
l2 = LinkedList()
l3 = LinkedList()
l1.sortedinsert(19)
l1.sortedinsert(16)
l2.sortedinsert(19)
l2.sortedinsert(15)
l2.sortedinsert(16)
l3.intersection(l1,l2)
node = l1.head
#Print all 3 linked list
print('List 1')
l1.display()
node = l2.head
print('List 2')
l2.display()
node = l3.head
print('List 3')
l3.display()
main()
修改相交方法
def intersection(self,l1,l2):
if l1==None and l2==None:
print("Linked lists are empty")
current_node = l1.head
current_node2 = l2.head
while current_node2!=None:
if current_node2.data==current_node.data:
self.sortedinsert(current_node2.data)
current_node2=current_node2.next
current_node=current_node.next
else:
current_node=current_node.next
if current_node==None:
current_node=l1.head
current_node2=current_node2.next
答案 1 :(得分:0)
如果在Node
中保存的数据是可散列的,我已经进行了一些更改/优化:
__str__
添加到类Node
和LinkedList
中,并删除了方法display
。您可以根据需要定制这些内容,但这是一种更加灵活的处理方式。例如,您想要将链接列表的输出写到磁盘文件而不是终端上的是什么?isempty
仅报告当前LinkedList是否为空,并且不打印任何内容。getsize
的工作效率更高。intersection
不需要排序的链表,并且非常有效。 它确实要求存储在节点中的数据是可散列的。例如,您不能在节点中存储list
,但可以存储元组。还将介绍intersection
的第二种实现方式,它没有该限制,但运行起来会更慢。我只是想提出另一个选择。 通常,人们希望能够以FIFO(先进先出)的顺序在列表中存储项目,如果实现排序插入的唯一原因是以后可能需要进行交集操作,则您可能想重新考虑一下。我的目的是向您展示一种不需要排序的链表的方法(但可以与它们一起使用!)。
更新的代码:
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
def __str__(self):
return "Node: " + str(self.data)
class LinkedList:
def __init__(self):
self.head = None
def __str__(self):
s = []
s.append('LinkedList:\n')
node = self.head
while node:
s.append(' ' * 4)
s.append(str(node))
s.append('\n')
node = node.next
return ''.join(s)
def sortedinsert(self, data):
current_node = self.head
if current_node==None:
new_node = Node(data)
self.head = new_node
return
if current_node.data > data:
new_node = Node(data)
new_node.next = current_node
self.head = new_node
return
while current_node.next is not None:
if current_node.next.data > data:
break
current_node = current_node.next
new_node = Node(data)
new_node.next = current_node.next
current_node.next = new_node
return
def delete(self, item):
current_node = self.head
if current_node and current_node.data == item:
self.head = current_node.next
current_node = None
return
previous_node = None
while current_node and current_node.data != item:
previous_node = current_node
current_node = current_node.next
if current_node is None:
return
previous_node.next = current_node.next
current_node = None
def deletebefore(self, value):
current_node = self.head
previous_node = None
if current_node.data == value:
print("There is no previous character")
return
while current_node.next.data != value:
previous_node = current_node
current_node = current_node.next
if current_node.next == None:
print("Given character not found")
return
if previous_node == None and current_node.next.data == value:
self.head = current_node.next
current_node = None
return
if current_node.next.data == value and previous_node:
previous_node.next = current_node.next
current_node = None
def update(self, prev_value, new_value):
new_value=Node(new_value)
current_node = self.head
while current_node.data != prev_value:
current_node = current_node.next
if current_node.data == prev_value:
current_node.data = new_value.data
return
def isempty(self):
return self.head is None
def getsize(self):
present_node = self.head
count = 0
while present_node is not None:
count += 1
present_node = present_node.next
return count
def getfirst(self):
current_node = self.head
if current_node:
print(current_node.data)
def intersection(self, l1, l2):
"""
This algorithm only works if the Node holds hashable data items.
"""
assert l1 and l2 # We assume people are passing us valid lists, which may be empty
self.head = None # to start out empty
if l1.isempty() or l2.isempty():
return
s1 = set()
current_node = l1.head
while current_node != None:
s1.add(current_node.data)
current_node = current_node.next
s2 = set()
current_node = l2.head
while current_node != None:
s2.add(current_node.data)
current_node = current_node.next
s_intersection = s1 & s2
for elem in s_intersection:
self.sortedinsert(elem)
def main():
l1 = LinkedList()
l2 = LinkedList()
l3 = LinkedList()
l1.sortedinsert(19)
l1.sortedinsert(16)
l2.sortedinsert(19)
l2.sortedinsert(15)
l2.sortedinsert(16)
l3.intersection(l1,l2)
print(l1)
print(l1.getsize())
print(l2)
print(l3)
main()
打印:
LinkedList:
Node: 16
Node: 19
2
LinkedList:
Node: 15
Node: 16
Node: 19
LinkedList:
Node: 16
Node: 19
更新
如果必须在节点中存储不可散列的项目,则可以使用以下交集实现:
def intersection(self, l1, l2):
assert l1 and l2 # We assume people are passing us valid lists, which may be empty
self.head = None # to start out empty
if l1.isempty() or l2.isempty():
return
list1 = []
current_node = l1.head
while current_node != None:
list1.append(current_node.data)
current_node = current_node.next
list2 = []
current_node = l2.head
while current_node != None:
list2.append(current_node.data)
current_node = current_node.next
list_intersection = [elem for elem in list1 if elem in list2]
for elem in list_intersection:
self.sortedinsert(elem)
答案 2 :(得分:0)
首先,您要确保如果链表中有相同的重复值,例如[1、2、2、3]和[0、2、2、3],则它们不会出现在相交处重复,即结果应为[2,3]。其次,如果对输入列表之一中的节点进行了更新,则相交处应该复制节点。看来您的update
方法可能会使LinkedList保持未排序状态。
def intersection(self, l1, l2):
"""
This assumes both lists are sorted. This assumption may not be true due
to method update possibly leaving list unsorted.
"""
assert l1 and l2 # We assume people are passing us valid lists, which may be empty
self.head = None # to start out empty
last_node = None
current_node_1 = l1.head
current_node_2 = l2.head
while current_node_1 and current_node_2:
if current_node_1.data > current_node_2.data:
current_node_1, current_node_2 = current_node_2, current_node_1 # if one is larger, make it current_node_2
if current_node_1.data < current_node_2.data:
current_node_1 = current_node_1.next
continue
# must be equal:
last_data = current_node_1.data
new_node = Node(last_data)
if last_node is None:
self.head = new_node
else:
last_node.next = new_node
last_node = new_node
while current_node_1 and current_node_1.data == last_data: # in case this value is not unique in the list
current_node_1 = current_node_1.next
while current_node_2 and current_node_2.data == last_data: # in case this value is not unique in the list
current_node_2 = current_node_2.next
def __and__(self, l):
"""
Usage:
l1 = LinkedList()
l2 = LinkedList()
l3 = l1 & l2 # performs intersection (ideally method intersection would never be invoked explicitly and should be renamed to _intersection)
"""
assert isinstance(l, LinkedList)
result = LinkedList()
result.intersection(self, l)
return result