感谢您提前阅读问题。
我正在通过Python研究链表数据结构。 下面两个方法push((,push1((困扰我。
类节点(对象(:
def __init__(self, value):
self.value = value
self.next = None
def __repr__(self):
nval = self.value and self.next.value or None
return f"[{self.value}:{repr(nval)}]"
类 LinkedListController(对象(:
def __init__(self):
self.begin = None
# Appends new value at the end of the list
def push(self, obj):
if not self.begin:
self.begin = Node(obj)
else:
n = self.begin
while n.next :
n = n.next
n.next = Node(obj)
def push1(self, obj):
if not self.begin:
self.begin = Node(obj)
else:
while self.begin.next:
self.begin = self.begin.next
self.begin.next = Node(obj)
# Counts the number of elements in the list
def count(self):
current_node = self.begin
count = 0
while current_node:
count = count + 1
current_node = current_node.next
return count
以下是测试代码:
from unittest import TestCase
from data_structure.single_linked_list_without_endnode import LinkedListController as node_controller
类 TestLinkedList(TestCase(:
def test_push(self):
colors = node_controller()
colors.push("Pathalon Blue")
self.assertEquals(colors.count(), 1)
colors.push("Ultramarine Blue")
self.assertEquals(colors.count(), 2)
colors.push("Blaring Sun")
self.assertEquals(colors.count(), 3)
animals = node_controller()
animals.push1("Dog")
self.assertEquals(animals.count(), 1)
animals.push1("Cat")
self.assertEquals(animals.count(), 2)
animals.push1("Cow")
self.assertEquals(animals.count(), 3)
push(( 和 push1((之间的唯一区别是引用"n",除此之外我看到了相同的逻辑,但为什么 push1(( 不起作用?
回溯(最近一次调用(: 文件"C:\用户\戴尔\项目\data_structure\测试\test_single_linked_list_without_endnode.py",第 24 行,test_push self.assertEquals(animals.count((, 3( 断言错误: 2 != 3
在第一种推送方法中,
n.next = Node(obj)
只是分配给参考数据"n",而不是分配给self.begin
。 而且我认为self.begin
应该仍然是 None ,因为我们没有做任何类似self.begin.next = Node(obj)
的事情,但测试工作正常。 如何。。?
多谢
push1(( 不起作用,因为你实际上是在改变 self.begin。 在 push(( 的情况下,你创建一个新对象并只给它对 self.begin 的引用,然后将这个引用更改为另一个对象(next(,而不改变属性本身,这样 self.begin 将保留操作后的第一个元素(在 push1(( 之后 self.begin 不是第一个元素,而是倒数第二个元素(。
在第一个推送方法中,它从self.begin
元素开始一直跟踪链表,直到到达链表中的最后一个元素,是的,它并不总是直接将您的self.begin
链接到您的新元素,但这就是链表作为数据结构的方式。
在push1()
方法中,通过在每次迭代中重新定义self.begin
来不断更改链表中的基本元素,因此链表将丢失其一些元素,考虑以下情况:您有 3 --> 5 --> 6 作为链表,例如,您使用push1()
添加元素 8, 它将做的是在第一次迭代中重新定义self.begin
,因此它变为 5,您的链表变为 5-->6,然后在下一次迭代中它仅成为元素 6,然后它附加您的新元素,因此它变为 6 --> 8,这就是为什么错误说2!=3
,因为push1()
总是会导致链表长度为 2