【问题标题】:Deleting a variables (pointer) value is not deleting the value it points to删除变量(指针)值不会删除它指向的值
【发布时间】:2019-04-01 04:30:21
【问题描述】:

我正在编写一个链表的实现,链表类及其节点如下所示:

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

class LinkedList:
    def __init__(self, head):
        self.head = head

    def insert(self, next):
        node = self.head
        while node.next:
            node = node.next

        node.next = next

    def remove(self, element):
        node = self.head
        while node:
            if node.element == element:
                if node.next:
                    node.element = node.next.element;
                    node.next = node.next.next;
                else:
                    print(node.element)
                    node = None;
                break;
            node = node.next

    def get(self, element):
        node = self.head
        while node:
            if node.element == element:
                return node
            node = node.next
        return None

我正在测试 remove 方法,但当我尝试删除链表的最后一个元素时它不起作用。在这种情况下,最后一个元素应设置为“None”,正如您在下面的 sn-p 中看到的(包含在上面的类中)。

def remove(self, element):
    node = self.head
    while node:
        if node.element == element:
            if node.next:
                node.element = node.next.element;
                node.next = node.next.next;
            else:
                node = None; #this will be fired
            break;
        node = node.next

但是,最后一个元素没有被删除,我不知道为什么。我假设node 将是指向最后一个元素的指针,并且值将设置为none,但它并没有被删除。这是失败的测试:

class Test(unittest.TestCase):
    def test_remove_node(self):
        head = Node('a', Node('b', Node('c')));
        ll = LinkedList(head);
        ll.remove('c');
        self.assertEqual(head.element, 'a');
        self.assertEqual(head.next.element, 'b');
        print(head.next.next.element);
        self.assertIsNone(head.next.next);

if __name__ == "__main__":
    unittest.main()

【问题讨论】:

  • node 在技术上是指向元素的指针(或“引用”)。如果将其设置为None,则设置此指针,但既不会修改元素本身,也不会更改指向同一元素的任何其他指针。
  • 虽然不是完全错误,但我发现您(不一致)使用分号有点令人不安:)

标签: python linked-list


【解决方案1】:

node 是一个临时局部变量,其中包含对感兴趣节点的附加 引用。将其设置为None 不会改变列表的结构,就像在循环的每次迭代中更新它一样:

                node
                  v
head -> a -> b -> c -> None

                       node
                         v
head -> a -> b -> c -> None

要正确更改列表的内容,您必须更新前一个节点中的指针。您可以通过在迭代时跟踪父级来做到这一点:

def remove(self, element):
     node, parent = self.head, None
     while node:
         if node.element == element:
              if parent:
                  parent.next = node.next
              else:
                  self.head = node.next
              break
          node, parent = node.next, node

您永远不需要复制元素,也永远不需要看过去node.next。简单地绕过包含感兴趣元素的节点就足够了。

【讨论】:

    猜你喜欢
    • 2012-08-05
    • 2015-08-09
    • 2018-01-23
    • 1970-01-01
    • 2013-09-24
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多