【问题标题】:How to delete a "node" which is passed to a method in a single linked list using Python如何使用Python删除传递给单个链表中方法的“节点”
【发布时间】:2016-10-26 13:07:42
【问题描述】:

我想实现 5 种方法来删除单个链表中的节点。

  1. 删除列表中的第一个元素 - 简单

  2. 删除列表中的最后一个元素 - 简单

  3. 删除某个位置的元素(数字) - 简单

  4. 删除具有给定值的元素 - 简单

  5. 删除特定节点 - 不知道该怎么做

我猜我面临的挑战是如何找到节点的内存地址或如何将节点的内存地址传递给方法。以下是我想出的代码。显然 " def delete_node(self, node):" 不起作用。以下是我目前想出的代码。

from Node import Node


class SingleLinkedList:

"""Constructor. Sets the length of the linkedlist to zero and initializes head reference"""
def __init__(self):
    self.head = None
    self.length = 0

""" Method to get the length of the list """
def get_list_length(self):
    return self.length

""" Method to INSERT a node at the beginning of the list """
def insert_at_beginning(self, data):
    new_Node = Node()
    new_Node.set_data(data)

    if self.length == 0:
        self.head = new_Node
    else:
        new_Node.set_next(self.head)
        self.head = new_Node
    self.length += 1

""" Method to INSERT a node at the end of the list """
def insert_at_end(self, data):
    new_Node = Node()
    new_Node.set_data(data)

    if self.length == 0:
        self.head = new_Node
    else:
        current = self.head
        while current.has_next():
            current = current.get_next()
        current.set_next(new_Node)
    self.length += 1

""" Method to INSERT a node at the given position, i.e. after postion - 1 . Position count start at 0 """
def insert_at_position(self, position, data):
    if position > self.length or position < 0:
        return None
    else:
        if position == 0:
            self.insert_at_beginning(data)
        else:
            if position == self.length:
                self.insert_at_end(data)
            else:
                new_Node = Node()
                new_Node.set_data(data)
                current = self.head
                count = 0
                while count < (position - 1):
                    current = current.get_next()
                    count += 1
                new_Node.set_next(current.get_next())
                current.set_next(new_Node)
                self.length += 1

""" Method to INSERT a new node to the list. Default insertion at the end of the list """
def add(self, data):
    self.insert_at_end(data)

""" Method to PRINT the elements of the list """
def print_list(self):
    if self.length == 0:
        return "Linked List is empty"
    else:
        current = self.head
        while current.has_next():
            print str(current.get_data()) + " ---> ",
            current = current.get_next()
        print str(current.get_data())

""" Method to DELETE the node at the beginning of the list """
def delete_at_beginning(self):
    if self.length == 0:
        return "List is empty"
    else :
        self.head = self.head.get_Next()
        self.length -= 1

""" Method to DELETE the node at the end of the list """
def delete_at_end(self):
    if self.length == 0:
        return "List is empty"
    else:
        current = self.head
        previous = None
        while current.has_next():
            previous = current
            current = current.get_next()
        previous.set_Next(None)
        self.length -= 1

""" Method to DELETE a node at the given position, i.e. after postion - 1 . Position count start at 0 """
def delete_at_position(self, position):
    if position > self.length or position < 0:
        return "Position does not exist"
    else:
        if position == 0:
            self.delete_at_beginning()
        elif position == self.length:
            self.delete_at_end()
        else:
            count = 0
            current = self.head
            previous = None
            while count < position:
                previous = current
                current = current.get_next()
                count += 1
            previous.set_next(current.get_next())
            self.length -= 1

""" Method to DELETE a node with a given value """
def delete_value(self, value):
    if self.length == 0:
        print " List is empty "
    else:
        current = self.head
        previous = None
        while current.has_next():
            if current.get_data() == value:
                break
            previous = current
            current = current.get_next()
        if current.get_data() != value:
            print "Item " + str(value) + " not in the list"
        else:
            previous.set_next(current.get_next())
            self.length -= 1

def delete_node(self, node):
    if self.length == 0:
        print "List is empty"
    else:
        current = self.head
        previous = None
        found = False
        while not found:
            if current == node:
                found = True
            elif current is None:
                print "Node not in the list"
                return
            else:
                previous = current
                current = current.get_next()
        if previous is None:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())
            self.length -= 1

def main():
    l = SingleLinkedList()
    print l.get_list_length()
    l.add(1)
    l.add(2)
    l.add(3)
    l.print_list()
    l.insert_at_beginning(500)
    l.insert_at_beginning(600)
    l.insert_at_beginning(700)
    l.print_list()
    l.insert_at_position(3, 99999)
    l.print_list()
    l.delete_at_position(3)
    l.print_list()
    l.delete_value(500)
    l.print_list()
    nd = Node()
    nd.set_data(2)
    l.delete_node(nd)
    l.print_list()

if __name__ == '__main__':
    main()

我正在关注一本用 C++ 编写的关于数据结构的书,并将其翻译成 Python。我想在 C++ 中传递内存地址很容易,也许这在使用 Python 时不可行?

任何帮助将不胜感激。

谢谢

编辑: 我有另一个与这门课有关的挑战。我希望能够迭代地和递归地找到链表的长度/大小。迭代地查找长度是直截了当的。我如何递归地找到长度?我能够在脑海中想象递归方法,但无法用 Python 编写代码。此外,这很令人困惑,因为 self 是参数中的第一个方法。

def sizeByIteration(self):
    current = self.head
    counter = 0
    while current is not None:
        counter += 1
        current = current.get_next()
    return counter

# def sizeByRecursion(self):
#     if self.head is None:
#         return 0
#     else:
#         self.head = self.head.get_next()
#         return 1 + self.sizeByRecursion()

【问题讨论】:

  • 在一个位置删除我们可以改变链接,保持两个指针,说p1=head,p2=head.next当p1到达你要删除的节点时改变p1.next=p2.next
  • 答案与 C++ 无关。 Pythonic 习语有很大的不同。
  • 你的意思是l.delete_node(nd)接近你的测试结束?这在 C++ 中也行不通。该节点根本不在列表中,因此无法从中删除。
  • 你的代码应该等同于delete_value(node.get_data())。忘记内存地址——你只是删除了传入的节点的值
  • 如果无法从外部访问列表的节点,即使在 C++ 中也无法进行此操作。

标签: python data-structures linked-list singly-linked-list


【解决方案1】:

您可能想尝试is 而不是==。如果两个变量引用同一个对象,is 将返回 True。而== 将使用默认比较器来比较对象的

试试这个:

def delete_node(self, node):
    if self.length == 0:
        print "List is empty"
    else:
        current = self.head
        previous = None
        found = False
        while not found:
            if current is node:
                found = True
            elif current is None:
                print "Node not in the list"
                return
            else:
                previous = current
                current = current.get_next()
        if previous is None:
            self.head = current.get_next()
        else:
            previous.set_next(current.get_next())
            self.length -= 1

另外需要注意的是:python 的好处是您可以编写非常短、简洁和功能性的代码。如果您了解该方法,请利用递归。如果您还没有上大学,请不要担心,继续您的快乐之路。

【讨论】:

  • 谢谢@Wesley Hoffman。关于递归。我明白什么是递归。事实上,我对递归的一个问题很感兴趣。我想使用迭代和递归找到链表的长度/大小。迭代地查找大小是直截了当的,但我不知道如何在 python 中作为类方法递归地执行此操作。你能帮我吗? # def sizeByRecursion(self): # if self.head is None: # return 0 # else: # self.head = self.head.get_next() # return 1 + self.sizeByRecursion()
  • @ShivKonar 我认为this 可能会为您指明一个好的方向!
【解决方案2】:

调用deleted_node()需要找到节点,只能从head遍历列表。

所以不是遍历两次,首先遍历本身我们可以删除节点

另外,通过递归查找长度 您编写的逻辑会修改整个列表,而这将起作用

def sizeByRecursion(self, node):
    if node is None:
       return 0
    return self.sizeByRecursion(node.get_next()) + 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多