如何在Python3中实现类C++的固定大小数组列表?
解决Python中模拟固定大小数组类的问题
首先得指出你原C代码里的一个关键问题:你试图用链表结构模拟数组,但错误地使用了指针算术(比如start + insertIndex)。在C中,new分配的链表节点并不是连续内存,这种指针加法属于未定义行为——它能运行只是巧合,逻辑上完全错误。这也是你移植到Python时碰壁的核心原因:Python没有直接的指针操作,而且这种思路本身就不符合链表/数组的正确实现逻辑。
接下来,我们用Python的语言特性重新实现这个固定大小的数组类,提供两种方案供你选择:
方案一:用Python列表作为底层存储(推荐,符合Python风格)
Python的list本身就是动态数组,我们可以通过限制它的大小,实现你需要的追加、检索、修改、删除功能,代码简洁且效率更高:
class FixedSizeList: def __init__(self, size): self.max_size = size self.items = [None] * size # 初始化固定大小的存储容器 self.current_length = 0 # 记录已添加元素的实际数量 def append(self, value): if self.current_length >= self.max_size: print("Error: List is full") return False self.items[self.current_length] = value self.current_length += 1 return True def retrieve(self, index): if index < 0 or index >= self.current_length: print("Index out of range!") return -1 return self.items[index] def remove(self, index): if index < 0 or index >= self.current_length: print("Index out of range!") return False # 将目标索引后的元素向前移动一位 for i in range(index, self.current_length - 1): self.items[i] = self.items[i + 1] self.items[self.current_length - 1] = None # 清空最后一个闲置位置 self.current_length -= 1 return True def change(self, index, value): if index < 0 or index >= self.current_length: print("Index out of range!") return False self.items[index] = value return True def print(self): for i in range(self.current_length): print(self.items[i]) # 测试代码 if __name__ == "__main__": list_obj = FixedSizeList(5) list_obj.append(1) list_obj.append(2) list_obj.append(3) list_obj.append(4) list_obj.append(5) print(list_obj.retrieve(0)) print(list_obj.retrieve(1)) print(list_obj.retrieve(2)) print(list_obj.retrieve(3)) print(list_obj.retrieve(4)) list_obj.remove(2) print("\nAfter removing index 2:") list_obj.print() list_obj.change(3, 8) print("\nChanged index 3 to 8:") print(list_obj.retrieve(3))
方案二:正确实现链表版本(如果坚持用链表结构)
如果你一定要用链表来模拟(虽然对于固定大小数组来说,链表不是最优选择),我们需要通过遍历链表定位节点,而不是试图用指针偏移:
class Item: def __init__(self, data=0, next_node=None): self.data = data self.next = next_node class FixedSizeLinkedList: def __init__(self, size): self.max_size = size self.current_length = 0 self.head = None self.tail = None # 初始化空节点,填充到指定大小 for _ in range(size): new_item = Item() if not self.head: self.head = new_item self.tail = new_item else: self.tail.next = new_item self.tail = new_item def _get_node_at_index(self, index): """辅助方法:获取指定索引对应的节点""" if index < 0 or index >= self.max_size: return None current = self.head for _ in range(index): current = current.next return current def append(self, value): if self.current_length >= self.max_size: print("Error: List is full") return False node = self._get_node_at_index(self.current_length) node.data = value self.current_length += 1 return True def retrieve(self, index): if index < 0 or index >= self.current_length: print("Index out of range!") return -1 node = self._get_node_at_index(index) return node.data def remove(self, index): if index < 0 or index >= self.current_length: print("Index out of range!") return False # 从目标索引开始,将后续节点的数据向前覆盖 current = self._get_node_at_index(index) while current.next: next_node = current.next current.data = next_node.data current = next_node current.data = 0 # 清空最后一个有效节点的数据 self.current_length -= 1 return True def change(self, index, value): if index < 0 or index >= self.current_length: print("Index out of range!") return False node = self._get_node_at_index(index) node.data = value return True def print(self): current = self.head count = 0 while current and count < self.current_length: print(current.data) current = current.next count += 1 # 测试代码 if __name__ == "__main__": list_obj = FixedSizeLinkedList(5) list_obj.append(1) list_obj.append(2) list_obj.append(3) list_obj.append(4) list_obj.append(5) print(list_obj.retrieve(0)) print(list_obj.retrieve(1)) print(list_obj.retrieve(2)) print(list_obj.retrieve(3)) print(list_obj.retrieve(4)) list_obj.remove(2) print("\nAfter removing index 2:") list_obj.print() list_obj.change(3, 8) print("\nChanged index 3 to 8:") print(list_obj.retrieve(3))
关键说明:
- 原C++代码的
start + insertIndex逻辑完全错误,因为链表节点不是连续内存,指针加法在这里没有实际意义,Python也不支持这种操作。 - 方案一利用Python内置列表实现,是Python中模拟固定大小数组的首选方式,代码简洁且性能更优。
- 方案二的链表版本通过遍历节点定位目标位置,符合链表的正确操作逻辑,彻底避开了指针算术的问题。
内容的提问来源于stack exchange,提问作者O'Niel
相关产品推荐
相关产品推荐

