链接列表删除指定值的所有实例

时间:2017-03-22 22:49:37

标签: python-3.x

我在删除链表中相同值的所有实例时遇到了很多麻烦。我理解这个问题与remove函数的self.head部分有关。

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


def getData(self):
    return self.data

def getNext(self):
    return self.next

def setData(self,newdata):
    self.data = newdata

def setNext(self,newnext):
    self.next = newnext


class UnorderedList:

def __init__(self):
    self.head = None

#Checks to see if the list is empty
def isEmpty(self):
    return self.head == None

#Adds the item at the beginning of the list
def add(self,item):        
    temp = Node(item)
    temp.setNext(self.head)
    self.head = temp

#Prints the Unordered List
def __str__(self):
    result = "["
    current = self.head
    if current != None:
        result += str(current.data)
        current = current.next
        while current:
            result += ", " + str(current.data)
            current = current.next
    result += "]"
    return result  

# Removes a specified item from the list
def remove(self, item):
    if self.head == None:
         return 'Cannot remove from an empty list'

    current = self.head     
    while current != None:
        iterator = current
        while iterator != None:
            prev = iterator
            iterator = iterator.getNext()
            if iterator is None:
                break
            if iterator.getData() == item:
                Next = iterator.getNext()
                prev.setNext(Next)
        current = current.getNext()



mylist = UnorderedList()

for i in range(50):
    mylist.add(2)
mylist.remove(2)
print(mylist)

结果:[2,2,2,2,2]

预期结果:[]

1 个答案:

答案 0 :(得分:0)

我认为你的remove代码比它需要的要复杂得多(使用嵌套循环等)。你应该能够让它更简单地工作。

这是我如何用两个循环,一个接一个地做到这一点。第一个循环用于引导节点,其中包含您要删除的值。第二个循环用于处理列表的其余部分。

def remove(self, item):
    if self.head == None:
        return 'Cannot remove from an empty list' # note, you may want to raise an exception

    while self.head is not None and self.head.data == item: # first loop, for leading values
        self.head = self.head.next

    if self.head is not None: # rest is only needed if the first loop didn't empty the list
        current = self.head
        while current.next is not None: # second loop, over all later items
            if current.next.data == item: # check for matching items
                current.next = current.next.next # and remove them
            else:
                current = current.next

我忽略了对getter和setter函数的调用,因为它们会分散注意力,而且在Python代码中通常不需要。在其他语言中使用getter和setter函数是一个很好的理由,但通常可以直接在Python中使用属性(如果需要更改,可以稍后将它们转换为property描述符如何在不改变API的情况下实施它们。如果这是一个家庭作业,你可能需要进行修复。

正如我在代码中所评论的那样,在第一个raise ValueError("cannot remove from an empty list")块中使用if之类的东西也可能是合适的,而不是将该错误消息作为字符串返回。 remove方法通常不返回任何内容(与返回None相同),因此除非您正在调用,否则很有可能无法注意到返回值来自交互式会话的功能。例外更有用,因为当它们发生在他们不期望的地方(这对于调试有利)时,它们会分解程序流。