【问题标题】:How can I reverse my singly linked list of nodes in Python?如何在 Python 中反转我的单链节点列表?
【发布时间】:2016-09-22 01:22:08
【问题描述】:

代码 sn-ps 如下:试图反转我的节点列表但是当我这样做时,只有一个节点(链接列表中的第一个)打印。知道我在这里做错了什么吗?我已经在纸上写了这个,它似乎应该遍历我的节点,将每个节点添加到我的新链表中?

# node class
class Node(object):
    def __init__(self, value, next=None):
        self.value = value
        self.next = next

# singly linked list class
class SinglyLinkedList(object):
    def __init__(self):
        self.head = None
        self.tail = None

# I'm trying to do the same thing in my reverseList() method
# as I'm doing in the addFront method
def addFront(self, value):
    # create new node
    newNode = Node(value)
    # set old head to point to new node
    if self.head == None:
        self.head = newNode
        self.tail = newNode
    else:
        # store old head
        last_head = self.head
        # set head to new node
        self.head = newNode
        # point head to old head
        self.head.next = last_head

# reverseList() method not working? 
# Only giving me first head value? Why?
def reverseList(self):
        node = self.head
        newList = SinglyLinkedList()
        newList.head = None
        while node:
            if node.next == None:
                break
            else:
                temp = newList.head
                newList.head = node
                newList.head.next = temp
                print newList.head.value
                node = node.next

【问题讨论】:

    标签: python-2.7 linked-list


    【解决方案1】:

    由于您设置了node == node.next,您的代码似乎跳过了列表的最后一个元素,然后询问node.next 是否有值。您的新列表还重用现有列表的节点,从而使它们共享对象。这不太可能是期望的行为,因为对一个列表的节点的任何更改都会导致对另一个列表的更改。特别是如果您向其中之一添加新元素,您会开始体验到您的列表表现得很奇怪。

    以下代码创建一个新列表,其中包含原始列表的相反顺序的值。

    def revers(self):
        rev = SinglyLinkedList()
        node = self.head
    
        while node:
            newNode = Node(node.value)
            if not rev.tail:
                rev.tail = newNode
            newNode.next = rev.head
            rev.head = newNode
            node = node.next
    
        return rev
    

    以下代码反转一个列表。

    def revers(self):
        prev = self.head
        next = self.head.next
        prev.next = None
    
        while next:
            temp = next.next
            next.next = prev
            prev = next
            next = temp
    
        self.head, self.tail = self.tail, self.head
    

    关于您的代码的评论。混合功能和命令式行为通常是一个坏主意。您的 addFront 函数修改列表对象,而您要求的反向函数创建一个新列表。您的所有函数都应该创建一个新列表,或者修改当前实例。像这样混合它会使您很难预测列表的行为。

    【讨论】:

    • 我无法要求更强有力的反馈,非常感谢您概述的所有内容,我现在明白您所说的有关功能性/命令性行为的内容 - 我正在反对墙试图找到这个解决方案,这是我进入命令式行为领域的一步,但是你已经完成的(反转现有列表)是一流的,也是我正在寻找的确切解决方案。已接受答案,您的反馈和贡献将受到高度重视!
    【解决方案2】:

    部分问题出现在newList.head = node 分配,然后是:newList.head.next = temp。第一行使这两个引用指向同一个事物,而下一行现在将改变两者(因为它们现在可以互换使用)。

    我认为您需要将前一个头部分配到新列表的尾部:

    def reverseList(self):
        node = self.head
        newList = SinglyLinkedList()
        newList.head = None
        while node:
            if node.next == None:
                break
            else:
                temp = newList.head
                newList.head = node
                newList.tail = temp
                print newList.head.value
                node = node.next
    

    编辑:如果您不介意创建仅包含旧节点对象值的新节点(对象)(我认为 addFront 正在这样做),您应该能够简单地替换:

    newList.head = node
    

    newList.head = Node(node.value, node.next)
    

    在您的原始帖子中

    【讨论】:

    • 我很欣赏这个反馈:为了解释,我试图模拟我构建的工作方法“addFront()”,它将值添加到链表的前面。我使用 reverseList() 的目标是 (1) 创建一个新列表 (2) 将新列表的头部设置为旧列表的头部 (3) 在替换时将旧列表中的下一项添加到新列表中当前头与新项目,然后将新项目链接到旧头(作为其下一个属性)。我将 addFront() 方法添加到上面的代码中——我想要完成的工作/我的逻辑是否更有意义?
    • @nature Mind:我认为我理解(但不是肯定的)-我编辑了我的答案
    • 非常感谢您在这里为我提供帮助的所有辛勤工作,我确实使用更新的 Node 代码尝试了您的解决方案,但我的列表似乎仍然是相同的顺序。我感觉它已经接近了,但我认为 Jonas 的方法比我尝试的要干净一些。我真的很感谢你试图帮助我理解我的代码:)
    【解决方案3】:

    我们可以通过递归函数来反转列表

    def reverse (item, tail = None):
        next = item.next
        item.next = tail
        if next is None:
            return item
        else:
            return reverse(next, item)
    

    参考访问:http://www.geeksforgeeks.org/reverse-a-list-in-groups-of-given-size/

    【讨论】:

    • 我确实尝试了您的解决方案并感谢您的反馈!当我运行上面的代码 sn-p 时,我得到以下属性错误:AttributeError: 'SinglyLinkedList' object has no attribute 'next' -- 知道吗?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-06-15
    • 2011-10-31
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    相关资源
    最近更新 更多