[英]Inserting the common elements from two linked lists in a third linked list
I had been working on a program to take common elements from two linked lists and append those elements into a third linked list.我一直在开发一个程序,以从两个链表中获取公共元素,并将 append 这些元素放入第三个链表中。 I was able to print out the common elements (nodes) from the two linked lists but i am unable to append those elements in a third linked list.
我能够从两个链表中打印出公共元素(节点),但我无法在第三个链表中 append 那些元素。 Any sort of help would really be appreciated: This is the complete code:
任何形式的帮助将不胜感激:这是完整的代码:
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
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)
main()
Below is the part of the program that involves intersection of two lists:以下是涉及两个列表交集的程序部分:
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)
main()
Problem is in intersection() method where you are re-initializing the current_node3.问题在于您正在重新初始化 current_node3 的 intersection() 方法。 Below is the fix for the same
以下是相同的修复
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()
Modifiying intersect method修改相交方法
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
I have made a few changes/optimizations that are applicable if the data being held in a Node
are hashable:如果
Node
中保存的数据是可散列的,我已经进行了一些适用的更改/优化:
__str__
to classes Node
and LinkedList
and removed method display
.__str__
添加到类Node
和LinkedList
并删除方法display
。 You can custom tailor these to your needs, but this a much more flexible way of proceeding.isempty
just reports whether the current LinkedList is empty or not and does not print anything. isempty
只报告当前 LinkedList 是否为空并且不打印任何内容。getsize
is made more efficient. getsize
变得更有效率。intersection
does not require sorted linked lists and is very efficient. intersection
不需要排序的链表并且非常有效。 It does, however, require that the data stored in a node be hashable.list
in a node but you can store a tuple.list
,但可以存储元组。 A second implementation of intersection
will also be presented that does not have that limitation, but it will run more slowly.intersection
实现,但运行速度会更慢。 I just wanted to present another option. Generally people want to be able to store items in a list in a FIFO (first in first out) order and if the only reason why you are implementing sorted insertions is for a possible need to do an intersection operation later on, you might want to rethink this.通常,人们希望能够以 FIFO(先进先出)的顺序将项目存储在列表中,如果您实现排序插入的唯一原因是以后可能需要进行交集操作,您可能想要重新考虑这一点。 My purpose was to show you a way that does not require sorted linked lists (but will work with them.).
我的目的是向您展示一种不需要排序链接列表的方法(但可以使用它们。)。
The updated code:更新后的代码:
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()
Prints:印刷:
LinkedList:
Node: 16
Node: 19
2
LinkedList:
Node: 15
Node: 16
Node: 19
LinkedList:
Node: 16
Node: 19
Update更新
If you have to store unhashable items in a Node, then the following implementation of intersection can be used:如果您必须在节点中存储不可散列的项目,则可以使用以下交集实现:
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)
First, you want to make sure that if the linked lists have duplicated values that are in common, for example [1, 2, 2, 3] and [0, 2, 2, 3], that they do not appear in the intersection duplicated, ie the result should be [2, 3].首先,您要确保如果链表有重复的共同值,例如 [1, 2, 2, 3] 和 [0, 2, 2, 3],它们不会出现在交集重复,即结果应该是 [2, 3]。 Second, the intersection should be making copies of nodes in case an update is made to a node in one of the input lists.
其次,如果对输入列表之一中的节点进行更新,则交集应该制作节点的副本。 It would also appear that your
update
method will potentially leave your LinkedList unsorted.看起来您的
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.