不能只删除链接列表中的最后一个元素! (所有其他具有特定值的元素都会被删除)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不能只删除链接列表中的最后一个元素! (所有其他具有特定值的元素都会被删除)相关的知识,希望对你有一定的参考价值。

我试图从一个linkedlist中删除具有特定值的节点,我要删除所有节点,除了最后一个,对于给定的输入。我也添加了'elif'的情况下,特别是删除最后一个节点,但不知道为什么它不工作。我是一个相当新的编程和数据结构,无法确定错误的地方。请帮助我 :)

class Node:
  def __init__(self, value, next_node=None):
    self.value = value
    self.next_node = next_node

  def get_value(self):
    return self.value

  def get_next_node(self):
    return self.next_node

  def set_next_node(self, next_node):
    self.next_node = next_node

class LinkedList:
  def __init__(self, value=None):
    self.head_node = Node(value)

  def get_head_node(self):
    return self.head_node

  def new_beginning(self, new_value):
    new_node = Node(new_value)
    new_node.set_next_node(self.head_node)
    self.head_node = new_node

  def stringify_list(self):
    string_list = ""
    current_node = self.get_head_node()
    while current_node:
      if current_node.get_value() != None:
        string_list += str(current_node.get_value()) + "\n"
      current_node = current_node.get_next_node()
    return string_list

  def remove_node(self, value_to_remove):
    current_node = self.get_head_node()
    if current_node.get_value() == value_to_remove:
      self.head_node = current_node.get_next_node()
    else:
      while current_node:
        next_node = current_node.get_next_node()
        if next_node.get_value() == value_to_remove:
          current_node.set_next_node(next_node.get_next_node())
          current_node = None
        else:
          current_node = next_node

  def remove_all_nodes(self,remove_value):
    current_node = self.get_head_node()
    while current_node:
      if current_node ==self.get_head_node() and current_node.value== remove_value:
        self.head_node = current_node.get_next_node()
        current_node = self.get_head_node()
      else:
        next_node = current_node.get_next_node()
        if next_node!= None and next_node.value == remove_value:
          prev_node = current_node
          current_node.set_next_node(next_node.get_next_node())

          current_node = next_node.get_next_node()
        elif (next_node == None) and (current_node.value == remove_value):
          #current_node = None
          prev_node.set_next_node(None)
        else:
          prev_node = current_node
          current_node = next_node


link_list = LinkedList(13)
link_list.new_beginning(13)
link_list.new_beginning(14)
link_list.new_beginning(15)
link_list.new_beginning(100)
link_list.new_beginning(13)
link_list.new_beginning(133)
link_list.new_beginning(13)
link_list.new_beginning(199)
link_list.new_beginning(13)
link_list.new_beginning(13)

print(link_list.stringify_list())
#print(len(link_list))

link_list.remove_all_nodes(13)

print(link_list.stringify_list())

最后一个13仍然没有被删除,请提出修改建议,以便我也能删除这个节点。

答案

remove_node 函数。

elif (next_node == None) and (current_node.value == remove_value):
          current_node = None

在这部分 - 你没有改变列表本身,你改变了变量。current_node 并把 None 成。你真正想做的是改变 next_node 前一个节点的属性 None.

主要有两种方法。

  1. 当你在函数里面迭代的时候,你可以持有第二个变量,previous_node。当你要删除一个节点的时候,你把 previous_node(节点) next_node(属性)改成跳过一个。如果是最后一个,你把他的next_node改为none。

  2. 使它成为一个双连接的列表,其中每个节点也持有他的前一个节点。这样更容易迭代。本质上是相同的逻辑,你必须去前一个节点,并改变他的下一个节点为none。只是更容易然后持有第二个变量。

编辑。 在你编辑了你的代码并实现了 previous_node之后, 你的代码中仍然有一个问题. 这里是一个固定的代码。

    def remove_all_nodes(self,remove_value):
        current_node = self.get_head_node()
        while current_node:
            if current_node == self.get_head_node() and current_node.value == remove_value:
                self.head_node = current_node.get_next_node()
                current_node = self.get_head_node()
            else:
                next_node = current_node.get_next_node()
                prev_node = current_node
                if next_node != None and next_node.value == remove_value:
                    current_node.set_next_node(next_node.get_next_node())
                elif (next_node == None) and (current_node.value == remove_value):
                    prev_node.set_next_node(None)
                    current_node = None
                else:
                    current_node = next_node

你的代码(编辑后的版本)有少许改动:

  1. prev_node声明应该在if语句之外,因为你想在某些情况下使用它的值。

  2. 删除了这一行 current_node = next_node.get_next_node() 的第一条语句。你目前的逻辑是:往前看一个节点,如果需要就把它取出来,然后推进当前节点。但是当你在行中有2个值(例如13)时,会发生什么情况呢?你不能删除它,因为你总是先删除一个节点。这里的问题不是 "最后一个元素",而是 "一行2个元素"。当我删除这一行后:当一个节点从列表中删除后,它只是在当前节点上再次进行迭代。这就是为什么它会不断地删除下一个节点,只有在 "安全 "的情况下才会前进。

现在输出的结果和预期的一样

以上是关于不能只删除链接列表中的最后一个元素! (所有其他具有特定值的元素都会被删除)的主要内容,如果未能解决你的问题,请参考以下文章

C语言 删除所有相同值的元素

Leetcode删除排序链表中的重复元素

如何删除一个list中最后一个元素

c_cpp 给定已排序的链接列表,删除所有具有重复数字的节点,只留下原始列表中的不同数字。

删除列表的最后一个元素(方案)

如何删除添加到列表中的最后一个元素?