【问题标题】:Inserting Into Linked List Python插入链表 Python
【发布时间】:2020-06-28 02:59:27
【问题描述】:

我在 python 中创建了一个非常标准的链表,其中包含 Node 类和 LinkedList 类。我还为 LinkedList 添加了如下方法:

  1. add(newNode):将元素添加到链表中
  2. addBefore(valueToFind, newNode):在具有指定值的元素之前添加一个新节点。
  3. printClean:打印链表

我正在尝试使用 addBefore 方法执行插入,但是如果插入不在头部,它将不起作用。我不知道为什么。

class Node:
    def __init__(self, dataval =None):
        self.dataval = dataval
        self.nextval = None

class LinkedList:
    def __init__(self, headval =None):
        self.headval = headval

    def add(self, newNode):
        # The linked list is empty
        if(self.headval is None):
            self.headval = newNode
        else:
            # Add to the end of the linked list
            currentNode = self.headval
            while currentNode is not None:
                # Found the last element
                if(currentNode.nextval is None):
                    currentNode.nextval = newNode
                    break
                else:
                    currentNode = currentNode.nextval


    def addBefore(self, valueToFind, newNode):
        currentNode = self.headval
        previousNode = None
        while currentNode is not None:
            # We found the element we will insert before
            if (currentNode.dataval == valueToFind):
                # Set our new node's next value to the current element
                newNode.nextval = currentNode

                # If we are inserting at the head position
                if (previousNode is None):
                    self.headval = newNode
                else:
                    # Change previous node's next to our new node
                    previousNode.nexval = newNode
                    return 0

            # Update loop variables
            previousNode = currentNode
            currentNode = currentNode.nextval
        return -1

    def printClean(self):
        currentNode = self.headval
        while currentNode is not None:
            print(currentNode.dataval, end='')
            if(currentNode.nextval != None):
                print("->", end='')
                currentNode = currentNode.nextval
            else:
                return

testLinkedList = LinkedList()
testLinkedList.add(Node("Monday"))
testLinkedList.add(Node("Wednesday"))
testLinkedList.addBefore("Wednesday", Node("Tuesday"))
testLinkedList.printClean()

星期一->星期三

【问题讨论】:

  • 嗨,你这里有一个错字:``` # 将前一个节点的旁边更改为我们的新节点 previousNode.nexval = newNode, change to previousNode.nextval = newNode```会做。
  • "is None" 有时会导致奇怪的意外问题,通常最好对所有条件使用简单的 Python 真实性。例如:stackoverflow.com/questions/6497166/…

标签: python data-structures linked-list


【解决方案1】:

这里有一个修复程序,它改变了您查找下一个要插入的节点的方式,并单独处理任何头部插入。我还更改了变量和类属性的名称以使事情更清晰:

class Node:
    def __init__(self, dataval=None):
        self.dataval = dataval
        self.nodepointer = None

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

由于每个节点都包含对下一个节点的引用,因此称为节点指针。这在这里有帮助(我认为):

    def addBefore(self, valueToFind, newNode):

        currentNode = self.headnode

        if currentNode.dataval == valueToFind:    #treat the front-end insertion as a 
            newNode.nodepointer = self.headnode   #special case outside the while loop
            self.headnode = newNode
            return -1

        while currentNode.nodepointer:            #notice lose all the 'is None' syntax
            # We found the element we will insert before *by looking ahead*
            if currentNode.nodepointer.dataval == valueToFind:
                # Set our new node's next *reference* to the current element's *next ref*
                newNode.nodepointer = currentNode.nodepointer
                currentNode.nodepointer = newNode  #now link 'previous' to new Node
                return -1                
            # Update loop variables
            currentNode = currentNode.nodepointer  #if this is None, while loop ends
        return 0

我认为这更像是一个传统的 C 风格的链表。

【讨论】:

    【解决方案2】:

    要详细说明 Satvir Kira 的评论,请使用此测试工具

    monday = Node("Monday")
    tuesday = Node("Tuesday")
    wednesday = Node("Wednesday")
    
    testLinkedList = LinkedList()
    testLinkedList.add(monday)
    testLinkedList.add(wednesday)
    testLinkedList.addBefore(wednesday.dataval, tuesday)
    
    print (monday.__dict__)
    print (tuesday.__dict__)
    print (wednesday.__dict__)
    

    输出:

    {'dataval': 'Monday', 'nextval': Wednesday, 'nexval': Tuesday->Wednesday}
    {'dataval': 'Tuesday', 'nextval': Wednesday}
    {'dataval': 'Wednesday', 'nextval': None}
    

    尽管我们确定将 nexval 设置为星期二,但星期一仍然指向星期三。等等,星期一也有 'nexval' 到星期二,还有 'nextval' 到星期三...... 错字!!! nexval 和 nextval 完全不同!

    哦,是的,我的打印有该输出,因为我将它添加到类节点:

    def __repr__(self):
        if self.nextval:
            return self.dataval + '->' + self.nextval.dataval
        return self.dataval
    

    【讨论】:

      【解决方案3】:

      你有一个错字,见下面方法addBefore中的#TODO:

          def addBefore(self, valueToFind, newNode):
          currentNode = self.headval
          previousNode = None
          while currentNode is not None:
              # We found the element we will insert before
              if (currentNode.dataval == valueToFind):
                  # Set our new node's next value to the current element
                  newNode.nextval = currentNode
      
                  # If we are inserting at the head position
                  if (previousNode is None):
                      self.headval = newNode
                  else:
                      # Change previous node's next to our new node
                      previousNode.nexval = newNode #TODO: Fix Typo: nexval
                      return 0
      
              # Update loop variables
              previousNode = currentNode
              currentNode = currentNode.nextval
          return -1
      

      【讨论】:

        【解决方案4】:

        希望对你有帮助

        def addBefore(self, valueToFind, newNode):
                currentNode = self.headval # point to headval
                previousNode = None 
                while currentNode.data != valueToFind: # while currentNode.data is not equal to valueToFind, move currentNode to next node and keep track of previous node i.e. previousNode
                    previousNode = currentNode # keep tack of previous node
                    currentNode = currentNode.nextval # move to next node
        
                previousNode.nextval = newNode # previous node will point to new node
                previousNode = previousNode.nextval # move previous node to newly inserted node
                previousNode.nextval = currentNode # previous node ka next will to currentNode
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-10
          • 1970-01-01
          • 1970-01-01
          • 2017-08-27
          • 2013-02-28
          • 2016-06-04
          • 1970-01-01
          相关资源
          最近更新 更多