将两个链表中的公共元素插入第三个链表中

时间:2020-04-28 18:42:44

标签: python python-3.x python-2.7

我已经找到了解决方案...感谢您的帮助!

3 个答案:

答案 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中保存的数据是可散列的,我已经进行了一些更改/优化:

  1. 已将方法__str__添加到类NodeLinkedList中,并删除了方法display。您可以根据需要定制这些内容,但这是一种更加灵活的处理方式。例如,您想要将链接列表的输出写到磁盘文件而不是终端上的是什么?
  2. isempty仅报告当前LinkedList是否为空,并且不打印任何内容。
  3. getsize的工作效率更高。
  4. 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