在python上的链表上实现一个insert方法



试图为单链表创建一个方法,却很难理解这个测试用例失败的原因。在我的第二个类SLinkedList中,我有一个名为insert的方法,它采用的参数pos是一个整数。现在,在我的测试用例中,当我将middle添加到位置4时,它停止引用任何其他节点——链表意味着包含数据middle的节点没有引用包含77的节点。我很困惑为什么会发生这种事?我对它进行了编程,当current_pos==pos时,我们将当前的下一个(new_node(设置为current.getNext(((77(。我没有把2的下一个分配给中间,把中间的下一个中分配给77吗?

class SLinkedListNode:
# an instance of this class is a node in a Single Linked List
# a node has a reference to data and reference to next
def __init__(self,initData,initNext):
self.data = initData
self.next = initNext
def getNext(self):
return self.next
def getData(self):
return self.data
def setData(self,newData):
self.data = newData
def setNext(self,newNext):
self.next = newNext

class SLinkedList:
# an instance of this class is a Singly-Linked List object
# it has reference to the first node in the list
def __init__(self):
self.head = None
self.size = 0
def add(self,item):
# adds an item at the start of the list
new_node = SLinkedListNode(item,None)
new_node.setNext(self.head)
self.head = new_node
self.size = self.size + 1
def append(self,item):
# adds an item at the end of the list
new_node = SLinkedListNode(item,None)
current = self.head # Start the traversal
if self.size == 0: # check if list is empty
self.add(item)
else:
while (current.getNext()!=None):
current= current.getNext() # traversing the list
current.setNext(new_node)
self.size = self.size +1

def insert(self,pos,item):
# inserts the item at pos
# pos should be a positive number (or zero) of type int
assert type(pos)==int,'Error:pos is not an integer'
assert pos>=0,'Error:pos must be positive'
current=self.head
new_node= SLinkedListNode(item,None)    
if pos==0:
self.add(item)
elif pos==self.size:
self.append(item)
else:
current_pos=0
while(current.getNext()!=None):

if (pos-1)==current_pos:
print(current.getData())
current.setNext(new_node)
if pos==current_pos:
print(current.getData())
new_node.setNext(current.getNext())    
current=current.getNext()

current_pos+=1
self.size+=1

# 1--> 2--->inserteditem---> 3-->4---> 5---> 6             


# TO DO: write assert statement that tests if pos is int
# TO DO: write assert statement that tests that pos is not negative
# TO DO: COMPLETE THE METHOD 

def remove(self,item):
# remove the node containing the item from the list
if self.size == 0:
raise Exception('List is Empty')
current = self.head
previous = None
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if not found:
raise Exception('Item not in list')
else:
if previous == None: # the item is in the first node of the list
self.head = current.getNext()
else: # item is not in the first node
previous.setNext(current.getNext())
self.size = self.size -1
def index(self,item):
# finds the location of the item in the list
if self.size == 0:
raise Exception('List is empty')
position = 0
found = False
current = self.head
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
position = position + 1
if found:
return position
else:
return 'Item not found'
def pop(self):
# removes the node from the end of the list and returns the item 
if self.size == 0:
raise Exception('List is empty')
current = self.head
previous = None
while current.getNext() != None:
previous = current
current = current.getNext()
if previous == None:
self.head = None
else:
previous.setNext(None)
self.size = self.size -1
return current.getData()
def __str__(self):
# returns a string representation of the list
current = self.head
string = ''
while current != None:
string = string + str(current.getData())+'->'
current = current.getNext()
return string
def getSize(self):
return self.size

def main():
# Testing Singly-Linked List
slist = SLinkedList()
slist.add(2)
slist.add(4)
slist.add('A')
slist.append(77)
slist.append(6)
slist.append('Z')
print('Original List:', slist.getSize(), 'elements')
print(slist)
print()
slist.insert(0,'start')
print('After inserting the word start at position 0:', slist.getSize(), 'elements')
print(slist)
print()
slist.insert(7,'end')
print('After inserting the word end at position 7:', slist.getSize(), 'elements')
print(slist)
print()
slist.insert(4,'middle')
print('After inserting middle at position 4:', slist.getSize(), 'elements')
print(slist)
if __name__=="__main__":
main()

看看insert-方法中的代码片段:

else:
current_pos=0
while(current.getNext()!=None):
if (pos-1)==current_pos:
print(current.getData())
current.setNext(new_node)
if pos==current_pos:
new_node.setNext(current.getNext())    
current=current.getNext()
current_pos+=1

一旦满足第一个if-条件,就将新节点设置为当前节点的下一个节点。请记住,这个新节点没有引用列表的其余部分。第二个if语句在此迭代期间不会执行,因此要执行的下一行是current=current.getNext(),它将current设置为新节点,仍然不引用列表的其余部分。因此,在while循环的下一次迭代中,current.getNext()计算为None,并且您的迭代立即终止,从而有效地从列表中删除了新节点之后的所有节点。

要解决此问题,请删除第二个if,并在上一个if语句中设置新节点的下一个节点。通过这种方式,您将保留对列表其余部分的引用。


附带说明一下,get-和set-方法非常不同步,您可以直接访问和修改这些属性,例如使用current.next = whatever。此外,while循环迭代整个列表对于插入任务来说似乎效率相当低,因为您确切地知道要将新节点插入的索引。此外,您的insert-方法将中断大于列表长度的位置,您可能需要为该添加另一个检查

相关内容

  • 没有找到相关文章

最新更新