链表tail属性失效:如何修改append函数实现尾节点正确指向?
问题描述
需要为无序列表添加tail属性使其始终指向最后一个节点,同时修改append函数,让它直接使用tail而非从head开始遍历。原append函数如下:
def append(self, item): current = self.head if current: while current.get_next() != None: current = current.get_next() current.set_next(Node(item)) else: self.head = Node(item)
修改后的append函数无报错但测试无输出,相关代码如下:
def append(self, item): current = self.tail if current: current = current.set_next(item) self.tail = current else: self.tail = Node(item)
完整类代码:
class Node: def __init__(self, node_data): self._data = node_data self._next = None def get_data(self): return self._data def set_data(self, node_data): self._data = node_data data = property(get_data, set_data) def get_next(self): return self._next def set_next(self, node_next): self._next = node_next next = property(get_next, set_next) def __str__(self): return str(self._data) class UnorderedList: def __init__(self): self.head = None self.tail = None def is_empty(self): return self.head == None def append(self, item): current = self.tail if current: while current.get_next() != None: current = current.get_next() current = current.set_next(Node(item)) else: self.tail = Node(item)
问题原因分析
- 空链表处理缺失:当链表为空时,只设置了
self.tail,但self.head仍然是None,后续遍历链表(比如打印)会因为找不到起始节点而无输出。 - 错误的赋值操作:
set_next方法是设置节点的_next属性,它没有返回值(默认返回None),所以current = current.set_next(Node(item))会把current变成None,再赋值给self.tail会导致tail丢失指向。 - 冗余的遍历逻辑:既然
tail已经指向最后一个节点,不需要再用while循环遍历找尾节点,完全是多余操作。
修正后的代码
class Node: def __init__(self, node_data): self._data = node_data self._next = None def get_data(self): return self._data def set_data(self, node_data): self._data = node_data data = property(get_data, set_data) def get_next(self): return self._next def set_next(self, node_next): self._next = node_next next = property(get_next, set_next) def __str__(self): return str(self._data) class UnorderedList: def __init__(self): self.head = None self.tail = None def is_empty(self): return self.head == None def append(self, item): new_node = Node(item) if self.is_empty(): # 空链表时,head和tail都指向新节点 self.head = new_node self.tail = new_node else: # 非空时,直接让tail的next指向新节点,再更新tail为新节点 self.tail.set_next(new_node) self.tail = new_node # 新增打印链表的方法,方便测试 def print_list(self): current = self.head while current: print(current.data, end=" -> ") current = current.next print("None") # 测试代码 ul = UnorderedList() ul.append(1) ul.append(2) ul.append(3) ul.print_list() # 输出:1 -> 2 -> 3 -> None
关键修正点
- 空链表时同时设置
head和tail,保证链表的起始节点和尾节点都被正确初始化。 - 非空链表时,直接操作
tail的next属性指向新节点,再把tail更新为新节点,避免不必要的遍历。 - 避免将
set_next的返回值(None)赋值给变量,因为set_next是一个无返回值的设置方法。
内容的提问来源于stack exchange,提问作者ty chen
相关产品推荐
相关产品推荐

