双向链表在循环python中某个节点结束后插入

Posted

技术标签:

【中文标题】双向链表在循环python中某个节点结束后插入【英文标题】:doubly_linked list Insert after a certain node ends in loop python 【发布时间】:2022-01-20 12:53:02 【问题描述】:

尝试学习Python中的数据结构,实现双向链表。当我试图在一个元素之后插入一个新元素时,它会以一个连续的循环结束。请尝试解释我哪里出错了,为什么会结束它连续循环。

我在这里发布我的整个代码,但问题在于 insertAt。请帮忙。

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class Double_list:
    def __init__(self):
        self.head = None
    
    def beginning(self, data):
        node = Node(data)
        if not self.head:
            self.head = node
        else:
            temp = self.head
            node.next = temp
            temp.prev = node

    def addelement(self, data):
        node = Node(data)
        if not self.head:
            self.beginning(data)
            return
        temp = self.head
        last = temp
        while temp.next:
            temp = temp.next
        temp.next = node
        node.prev = temp
    
    def ending(self, data):
        self.addelement(data)

    def insertAt(self, data, after=None):
        node = Node(data)
        temp = self.head
        while temp and after:           
            import pdb; pdb.set_trace()
            last = temp
            temp = temp.next
            if last.data == after:
                last.next = node
                node.prev = last
                node.next = temp
                temp.prev = node
            

    def remove(self,data):
        temp = self.head
        while temp:
            if temp.data == data:
                break
            last = temp
            temp =temp.next
        last.next = temp.next
        temp.next.prev = last

    def printll(self):
        temp = self.head
        while temp:
            print (temp.data, end=" ")
            temp = temp.next

obj = Double_list()
obj.beginning(1)
obj.addelement(2)
obj.ending(3)
obj.insertAt(data=4,after=1)
obj.remove(2)
obj.printll()

【问题讨论】:

为什么你的insertAt 有一个before 参数?它从未使用过...请同时提供重现问题的(最小)驱动程序代码。 insertAt是否打算在after在列表中出现多次时插入多个节点? 嗨@trincot 感谢您的回复。不,它只打算添加单个元素。我已经修改了代码。 【参考方案1】:

由于insertAt 旨在插入最多一个 节点,因此您应该在添加后立即退出循环(break)。因为这不会在您的代码中发生,所以存在第二次添加 same 节点的风险(当after 第二次出现时),这将导致链表不一致.

该方法中的一些其他问题:

temp 恰好是None 时,您应该保护您的算法不访问temp.prev。 while 循环条件不应包含任何关于 after 的信息。 该函数没有使用before,所以这不应该是一个参数。 如果列表中没有找到after的值,则不应该插入节点,因此最好在找到after时才创建节点。

所以:

    def insertAt(self, data, after=None): # No `before`
        temp = self.head
        while temp:  # No condition on `after`
            last = temp
            temp = temp.next
            if last.data == after:
                node = Node(data)  # <-- moved!
                last.next = node
                node.prev = last
                node.next = temp
                if temp:  # avoid error
                    temp.prev = node
                break  # stop looking further

另一个说明:beginning 方法应该始终执行self.head = node,即使列表已经有节点。

【讨论】:

以上是关于双向链表在循环python中某个节点结束后插入的主要内容,如果未能解决你的问题,请参考以下文章

linux内核共享双向链表

Java中双向链表的代码实现

带头节点的双向链表

数据结构和算法-链表

线程概念与双向链表粗略比划

线程概念与双向链表粗略比划