删除Python双链表中的节点时出现问题

时间:2016-05-07 15:52:10

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

我一直在尝试在Python中创建一个双链表,但我在LinkedList类中遇到了一些方法。我希望我的removeFrontremoveRear方法返回已删除的值,但我无法使其工作。使用测试列表,如果我将一些值x输入节点并尝试将其删除,则不会返回x。

我认为删除节点的想法是通过将其下一个节点与其前一节点连接来将其从列表中删除,但感觉我对此的尝试存在根本缺陷。

我也在尝试实现pop方法(删除列表中的特定元素)但不知道从哪里开始。任何建议在这里向我推进正确的方向将不胜感激。谢谢。

class Node:

    def __init__(self,data):
        self.data = data
        self.next = None
        self.prev = None

class LinkedList:

    def __init__(self):
        self.front = None
        self.rear = None

    def isEmpty(self):
        return self.front is None and self.rear is None

    def addFront(self, data):
        new_node = Node(data)
        if self.front is None:
            self.front = new_node
            self.rear = self.front
            self.front.prev = None
            self.rear.next = None
        else:
            self.front.prev = new_node
            new_node.next = self.front
            self.front = new_node
            self.front.prev = None

    def addRear(self, data):
        new_node = Node(data)
        if self.front is None:
            self.rear = new_node
            self.front = self.rear
            self.front.prev = None
            self.rear.next = None
        else:
            self.rear.next = new_node
            new_node.prev = self.rear
            self.rear = new_node
            self.rear.next = None

    def removeFront(self):
        if self.isEmpty():
            return None
        else:
            removed = self.front
            self.front.prev = self.front
            self.front.prev.next = None
            return removed

    def removeRear(self):
        if self.isEmpty():
            return None
        else:
            removed = self.rear
            self.rear.prev = self.rear
            self.rear.prev.next = None
            return removed

    def pop(self, index):
        # TODO: How to implement?
        pass

    def size(self):
        current = self.front
        count = 0
        while current is not None:
            count += 1
            current = current.next
        return count

2 个答案:

答案 0 :(得分:1)

以下是带有评论的{ "rawatanSemulajadi": [ { "s_id" :"b004", "s_nama" :"zaitun", "s_perician" : "", "s_gambar":"img/delima.jpg" }, { "s_id" :"b005", "s_nama" :"delima", "s_perician" : "", "s_gambar":"" }, { "s_id" :"b006", "s_nama" :"epal", "s_perician" :" ", "s_gambar":"" }, { "s_id" :"b007", "s_nama" :"labu manis", "s_perician" :"", "s_img":"" }, { "s_id" :"b008", "s_nama" :"tomato", "s_perician" :"", "s_gambar":"" }, { "s_id" :"b009", "s_nama" :"bawang", "s_perician" :"", "s_gambar":"" }, { "s_id" :"b010", "s_nama" :"habbatus sauda", "s_perician" :"", "s_gambar":"" }, { "s_id" :"b011", "s_nama" :"rizom", "s_perician" :"", "s_gambar":"" }, { "s_id" :"b012", "s_nama" :"peria", "s_perician" :" 1.**Paling cepat diproses dan diserap, sekaligus memberikan tenaga segera", "s_gambar":"" }, { "s_id" :"b013", "s_nama" :"pisang", "s_perician" :"", "s_gambar":"" }, ], "penyakit":[ { "p_id" :"y111", "p_nama" :"cirit birit", "p_perician" : "", "p_gambar" : "", "s_id" : "b001, b003, b005, b009, b010" }, { "p_id" :"y112", "p_nama" :"sembelit", "p_perician" : "", "p_gambar" : "", "s_id" :"b001, b002, b005, b006" }, { "p_id" :"y113", "p_nama" :"demam", "s_id" :"b005, b006, b007, b009, b010" }, { "p_id" :"y114", "p_nama" :"buasir", "p_perician" : "", "p_gambar" : "", "s_id" :"b004, b005, b010, b013" }, { "p_id" :"y115", "p_nama" :"batuk", "p_perician" : "", "p_gambar" : "", "s_id" :"b003, b009, b010, b011" }, { "p_id" :"y116", "p_nama" :"bisul", "p_perician" : "", "p_gambar" : "", "s_id" :"b004, b008, b009, b010, b012" }, { "p_id" :"y117", "p_nama" :"sakit kepala", "p_perician" : "", "p_gambar" : "", "s_id" :"b002, b005, b011" }, { "p_id" :"y118", "p_nama" :"luka", "p_perician" : "", "p_gambar" : "", "s_id" :"b002, b013" }, ], "tahapPenyakit":[ { "t_id" :"L1", "t_nama" :"ringan", "p_id" : "y111, y112, y113, y114, y115, y116, y117, y118" }, { "t_id" :"L2", "t_nama" :"normal", "p_id" :"y111, y112, y113, y114, y115, y116, y117, y118" }, { "t_id" :"L3", "t_nama" :"berat", "p_id" :"y111, y112, y113, y114, y115, y116, y117, y118" }, ], "cara":[ { "p_id" :"y111", "s_id" :"b001, b003, b005, b009, b010", "c_ulasan" :"" }, { "s_id" :"b002", "p_id" :"y112, y122, y114", "c_ulasan" :"" }, { "s_id" :"b003", "p_id" :"y111,y113, y114, y115, y116, y124", "c_ulasan" :" " }, { "s_id" :"b004", "p_id" :"y118, y120,y121, y125", "c_ulasan" :"" }, { "s_id" :"b005", "p_id" :"y112, y113, y115, y117, y118, y120 ", "c_ulasan" :"" }, { "s_id" :"b006", "p_id" :"y114, y116", "c_ulasan" :"" }, { "s_id" :"b007", "p_id" :"y111, y112, y117, y124, y125", "c_ulasan" :"" }, { "s_id" :"b008", "p_id" :"y117", "c_ulasan" :"" }, { "s_id" :"b009", "p_id" :"y116", "c_ulasan" :"" }, { "s_id" :"b010", "p_id" :"y121", "c_ulasan" :"" }, { "s_id" :"b011", "p_id" :"y111, y119", "c_ulasan" :"" }, { "s_id" :"b012", "p_id" :"y111, y114, y117, y118, y119, y120, y125", "c_ulasan" :"" }, { "s_id" :"b013", "p_id" :"y111, y119, y121, y122, y123", "c_ulasan" : "" } ] } 的实施:

removeFront

def removeFront(self): if self.isEmpty(): return None # Store data so that it can be returned data = self.front.data if self.front == self.rear: # List contains one item, set front & rear to initial state self.front = self.rear = None else: # More than one item self.front = self.front.next # Set front to point next item self.front.prev = None # Front doesn't have previous item return data 完全符合相同的逻辑。

为了实施removeRear,您需要考虑三种不同的情况:

  • 正在移除前线
  • 正在删除后方
  • 正在删除前后节点

无论遇到什么情况,您仍需要找到要删除的正确节点。您可以在列表中前进的同时循环执行此操作。找到正确的节点后,如果它是第一个或最后一个节点,您可以使用popremoveFront。如果节点介于两者之间,则需要将其从之前的&下一个节点并将剩余的节点连接在一起。

答案 1 :(得分:0)

快速代码审核:

  • Node.__init__()是正确的。
  • LinkedList.__init__()是正确的。
  • LinkedList.isEmpty()是正确的。
  • LinkedList.size()是正确的。

以下是如何正确实施LinkedList.removeFront()

    def removeFront(self):
        if self.isEmpty():
            return None
        else:
            removed = self.front.data
            self.front = self.front.next
            if self.front is None:  # List size was 1
                self.rear = None
            else:
                self.front.prev = None
            return removed

我会将removeRear()的实施作为练习留给您。逻辑与removeFront()对称。

LinkedList.addFront()是正确的,但可以简化:

    def addFront(self, data):
        new_node = Node(data)
        if self.front is None:
            self.front = new_node
            self.rear = new_node
            #self.front.prev = None  # Already None
            #self.rear.next  = None  # Already None
        else:
            self.front.prev = new_node
            new_node.next = self.front
            self.front = new_node
            #self.front.prev = None  # Already None

您的LinkedList.addRear()是正确的,但可以采用相同的方式进行简化。

您询问了如何实施LinkedList.pop()。这将是一个棘手的问题。你必须考虑多个案例:

  • 如果列表只有一个元素怎么办?
  • 如果要删除的节点位于前端怎么办?
  • 如果要移除的节点位于后方怎么办?
  • 如果要删除的节点严格位于中间,该怎么办?