如何在Python中交换单链表节点?

2 投票
2 回答
3746 浏览
提问于 2025-04-18 16:01

目前,我正在尝试根据我的主函数 switch(myList,index) 来重新排列一个链表。

def createList(plist):
    linkedList = None
    # goes backwards, adding each element to the beginning
    # of the list.  
    for index in range(len(plist)-1, -1, -1):
        linkedList = insertValueHead(linkedList, plist[index])
    return linkedList

def insertValueHead(linkedList, value):
    newnode = {}
    newnode["data"] = value
    #set the next pointer of this new node to the head of the list, linkedList
    #newnode is now the head of the list 
    newnode["next"] = linkedList
    return newnode

def listString(linkedList):
   ptr = linkedList
   str1 = ''
   while ptr != None:
     str1 += str(ptr['data'])
     ptr = ptr['next']
     if ptr != None:
      str1 += "->"
  str1 = str1
  return str1

def switch(j, i):
   head = j
   currentItem = j[0]     # The head again
   prevItem = 1       # The item that links to tempItem
   for x in range(i):    # Find the item to swap
        prevItem = currentItem
        currentItem = currentItem['next']
        currentItem = currentItem['next']
        temp = currentItem['next']
        currentItem['next'] = head['next']
        head['next'] = prevItem['next']
        prevItem['next'] = temp

def testSwitch():
    #test code to ensure that switch() is working correctly.
    myList = createList([10, 20, 30, 40, 50, 60])
    print "The initial list", listString(myList)
    myList = switch(myList, 2)
    print "Switching the 1 and the 2.  Resulting list is ", listString(myList)

testSwitch()

这样应该能得到一个元素交换后的列表。但是,当我运行它时,输出是这样的:

The initial list 10->20->30->40->50->60
Switching the 1 and the 2.  Resulting list is 

接下来出现了这个错误:

    currentItem = currentItem['next']
TypeError: list indices must be integers, not str

我到底哪里出错了?我似乎搞不清楚……

2 个回答

-2

你的缩进不正确,这就是你遇到问题的原因。

def switch(j, i):
    head = j
    currentItem = j[0]     # The head again
    prevItem = 1       # The item that links to tempItem
    for x in range(i):    # Find the item to swap
        prevItem = currentItem
        currentItem = currentItem['next']
        currentItem = currentItem['next']
        temp = currentItem['next']
        currentItem['next'] = head['next']
        head['next'] = prevItem['next']
        prevItem['next'] = temp

在一个函数或循环里面,要缩进四个空格。你不能把 j[0] 赋值给当前项,因为它是一个字典。

2

单向链表在需要支持切换操作时并不是一个很实用的结构。如果使用双向链表,节点可以同时指向前后,这样就很简单了;但如果是单向链表,你至少得遍历一遍链表才能找到需要的节点。而且,你的代码看起来很乱,别人根本没法调试。因此,

  • 建议使用基于类的列表,而不是直接使用节点子类的项。
  • 如果你需要进行切换操作,真的应该使用双向链表。可以考虑使用Linux的链表约定,链表的两端也可以是一个列表节点。

类似于

 class Node(object):
     prev = None
     next = None

 class List(object):
     def __init__(self):
         self.head = self
         self.tail = self
         self.prev = self
         self.next = self
         self.nil = self

     def insert_head(self, node):
         node.next = self.head.next
         self.head.next.prev = node
         node.prev = self.head
         self.head.next = node

     def __iter__(self):
         current = self.head.next
         while current != self.nil:
             yield current
             current = current.next

     def __str__(self):  # the "list_string" op
         items = []
         return ' -> '.join(map(str, self))

 class TestNode(Node):
     def __init__(self, value):
         self.value = value

     def __repr__(self):
         return repr(self.value)

list = List()
list.insert_head(TestNode('a'))
list.insert_head(TestNode('b'))
print(list)

撰写回答