扭转双向链表的问题

时间:2016-10-06 22:53:32

标签: python linked-list doubly-linked-list

我必须在两个节点之间反转双向链表(DLL)。我用单链表(SLL)完成了这个,但我觉得用DLL做起来更难?可能是必须在两个特定节点之间进行。 这是我的DLLNode&的代码。 DLL。当我测试这段代码时,似乎对我的DLL没有任何作用。关于我做错的任何提示??

编辑:所以我输入一个链接列表'a','b','c','d','e','f'和call twist('b','e'):这个应该导致链表'a''b''e''d''c''f'

class DoublyLinkedListNode:
def __init__(self, item, prevnode = None, nextnode = None):
    self._data = item
    self.setnext(nextnode)
    self.setprev(prevnode)

def data(self):
    return self._data

def next(self):
    return self._next

def prev(self):
    return self._prev

def setprev(self, prevnode):
    self._prev = prevnode

def setnext(self, nextnode):
    self._next = nextnode

class DoublyLinkedList:
def __init__(self):
    self._head = None
    self._tail = None
    self._length = 0

def _newnode(self, item, nextnode = None, prevnode = None):
    return DoublyLinkedListNode(item, nextnode, prevnode)

def addfirst(self, item):
    if self.isempty():
        return self._addtoempty(item)
    node = self._newnode(item, None, self._head)
    self._head.setprev(node)
    self._head = node
    self._length += 1

def addlast(self, item):
    if self.isempty():
        return self._addtoempty(item)
    node = self._newnode(item, self._tail, None)
    self._tail.setnext(node)
    self._tail = node
    self._length += 1

def _addtoempty(self, item):
    node = self._newnode(item, None, None)
    self._head = self._tail = node
    self._length = 1

def removefirst(self):
    if len(self) <= 1:
        return self._removelastitem()
    data = self._head.data()
    self._head = self._head.next()
    self._head.setprev(None)
    self._length -= 1
    return data

def removelast(self):
    if len(self) <= 1:
        return self._removelastitem()
    data = self._tail.data()
    self._tail = self._tail.prev()
    self._tail.setnext(None)
    self._length -= 1
    return data

def _removelastitem(self):
    if self.isempty():
        return None # Should probably raise an error.
    data = self._head.data()
    self._head = self._tail = None
    self._length = 0
    return data

def twist(self, endpt1, endpt2):
    current = self._head
    while current != None:
        if current.data() == endpt1:
            current.next().setnext(endpt2.next())
            endpt2.setnext(current.next())
            current.setnext(endpt2)
        else:
            current = current.next()

def isempty(self):
    return len(self) == 0

def _nodes(self):
    node = self._head
    while node is not None:
        yield node
        node = node.next()

def __iter__(self):
    for node in self._nodes():
        yield node.data()

def __len__(self):
    return self._length

def __str__(self):
    items = [str(data) for data in self]
    return ", ".join(items)

这是我正在运行的测试:

    def testtwist1(self):
        n = [0,1,2,3,4,5]
        L = DoublyLinkedList()
        for i in n:
            L.addlast(i)
        L.twist(2,5)
        print(L)   # returns the list 0,1,2,3,4,5

1 个答案:

答案 0 :(得分:0)

我根本不知道这是如何执行的。您显然已经设置了一个DLL,然后调用了 DLL.twist(&#39; b&#39;,&#39; e&#39;)。因此,endpt1 =&#39; b&#39;和endpt2 =&#39; e&#39;。然后,将endpt1与current.data进行比较,然后访问endpt2.next。 endpt2是单字符字符串

您根本不会引用 prev 指针。

您尝试更改任何内容的唯一时间是您点击节点 b 。然后你似乎尝试交换 b e 下一个指针(所以 b.next f e.next c ,但这都是。

此时,我希望您的前向链接为您提供两个列表:a-&gt; b-&gt; f和c-&gt; d-&gt; e-&gt; c(一个循环),以及向后链接没有变化。

获取铅笔和纸或白板,并逐步完成这些更改,一次一个声明;这就是我做的......

我从您之前的帖子中恢复了扭曲,修复了缩进,然后运行了。正如我在上面解释的那样,执行中的这个错误:

Traceback (most recent call last):
  File "so.py", line 113, in <module>
    L.twist(2,5)
  File "so.py", line 102, in twist
    current.next().setnext(endpt2.next())
AttributeError: 'int' object has no attribute 'next'

没有 2.next()这样的东西。我不认为您实际上正在进行打印声明。此外, print(L)将不会按顺序打印节点值;您还没有为您的DLL对象添加 __ repr __ 方法。 __ str __ 可以完成这项工作,但您已经使用了列表头指针,就好像它是在前向链接列表上的可迭代一样。

我强烈建议您使用增量编程进行备份和处理:编写一个方法或几行,测试一下,并且不要继续,直到它按预期工作。是的,这意味着你在去的时候写下详细的测试......这是一件好事。保留它们,并继续运行它们。