Python-从开头,中间和结尾从链表中删除节点

时间:2020-07-19 18:40:33

标签: python nodes

我今天了解了链表。我学习了如何从中插入和删除节点。在下面的代码中,它教我如何插入具有三个不同功能的节点:在开始(头节点),在中间和结尾。但是,他们教我如何在单功能中删除节点。我在remove函数中找不到很清楚的代码。有人可以在remove函数下帮助简化代码吗?有没有办法像插入函数一样将其分为三个函数?我愿意接受任何建议或解释。预先感谢。

这是我的代码:

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

class LinkedList:
    def __init__(self):
        self.headnode = None

    def printlist(self):
        node = self.headnode
        while node is not None:
            print (node.data)
            node = node.nextnode

    def atbegining(self,new_node):
        new_node.nextnode = self.headnode
        self.headnode = new_node

    # Function to add newnode
    def AtEnd(self, newnode):
        if self.headnode is None:
            self.headnode = newnode
            return
        node = self.headnode
        while(node.nextnode):
            node = node.nextnode
        node.nextnode=newnode

    # Function to add node
    def Inbetween(self,preNode,newNode):
        if preNode is None:
            print("The mentioned node is absent")
            return
        newNode.nextnode = preNode.nextnode
        preNode.nextnode = newNode

    # Function to remove node
    def RemoveNode(self, RemoveVal):

        node = self.headnode

        if (node is not None):
            if (node.data == RemoveVal):
                self.headnode = node.nextnode
                node = None
                return

        while (node is not None):
            if node.data == RemoveVal:
                break
            prevnode = node
            node = node.nextnode

        if (node == None):
            return

        prevnode.nextnode = node.nextnode

        node = None


list1 = LinkedList()
list1.headnode = Node("Mon")
n2 = Node("Tue")
n3 = Node("Wed")
# Link first Node to second node
list1.headnode.nextnode = n2
# Link second Node to third node
n2.nextnode = n3
n4 = Node("Sun")
n5 = Node("Tur")
n6 = Node("Newdate")

list1.atbegining(n4)
list1.AtEnd(n5)

list1.Inbetween(list1.headnode,n6)
list1.RemoveNode("Newdate")
list1.printlist()

2 个答案:

答案 0 :(得分:1)

我认为替代设计会使代码更清晰。例如,考虑以下内容:

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

    def printlist(self):
        print(self.data)
        if self.nextnode is not None:
            self.nextnode.printlist()

    def push(self, node):
        node.nextnode = self
        return node

    def insertafter(self, node):
        node.nextnode = self.nextnode
        self.nextnode = node
        return self

    def append(self, node):
        lastnode = self
        while lastnode.nextnode is not None:
            lastnode = lastnode.nextnode

        lastnode.nextnode = node
        return self

    def remove(self, value):
        prev = None
        walk = self

        while walk is not None:
            if walk.data == value:
                if prev is None:
                    return walk.nextnode
                else:
                    prev.nextnode = walk.nextnode
                    return self
            else:
                prev = walk
                walk = walk.nextnode

        return self

list1 = Node("Mon")
n2 = Node("Tue")
n3 = Node("Wed")
# Link first Node to second node
list1 = list1.insertafter(n2)
# Link second Node to third node
n2 = n2.insertafter(n3)
n4 = Node("Sun")
n5 = Node("Tur")
n6 = Node("Newdate")

list1 = list1.push(n4)
list1 = list1.append(n5)

list1 = list1.insertafter(n6)
list1 = list1.remove("Newdate")
list1.printlist()

主要思想是Node是链表。只要将列表的开头保留在变量中,就可以访问整个列表,而无需单独的数据结构。

答案 1 :(得分:1)

RemoveNode由于存在两种LinkedList结构上不同的事实而变得复杂:一种是其头为None,而另一种是其头不是None。您可以通过确保每个LinkedList至少包含一个节点来解决此问题。通常将其称为虚拟节点,您可以使用此节点存储元数据(例如列表的长度)。

Node类本身不会更改。

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

LinkedList通过创建虚拟节点来简化。这提供 确保每个存储真实数据的节点都指向另一个节点。

class LinkedList:
    def __init__(self):
        self.headnode = Node(0)

    def insert(self, preNode, newNode):
        newNode.nextnode = preNode.nextnode
        preNode.nextnode = newNode
        self.headnode.data += 1

    def append(self, newNode):
        curr = self.headnode
        while curr.nextNode is not None:
            curr = curr.nextNode

        self.insert(curr, newNode)

    def prepend(self, newNode):
        self.insert(self.headnode, newNode)

    def _find_before(self, val):
        pre = self.headnode
        while pre.nextnode is not None:
            curr = pre.nextnode
            if curr.data == val:
                return pre
            pre = curr

    def remove(self, RemoveVal):
        pre = self._find_before(RemoveVal)
        if pre is None:
            return
        pre.nextnode = pre.nextnode.nextnode
        self.headnode.data -= 1

这简化了所有三个插入。一般情况下,总可以适用,因为在插入的节点之前总是有一个节点。 appendprepend是简单的包装程序,它们找到要传递给insert的适当节点。 同样,remove只是在给定值之前处找到节点,如果搜索成功,则处理更新先前节点的nextnode属性。

insertremove也会更新虚拟节点中存储的列表的大小。

find方法成为_find_before周围的简单包装;如果在要查找的值之前找到一个节点,则只需返回其后的节点即可。