python中带有特殊方法的单链表,卡住了
一个带有两个类的单链表,Node和LinkedList,很容易实现。然而,我的问题是当涉及到只有第一个节点访问的单链表时(没有存储长度,没有最后一个节点访问,并且没有使用虚拟节点)。我无法在网上了解的特殊方法类似于pythons内置的列表操作,复杂性为O(1),如下所示:python中带有特殊方法的单链表,卡住了,python,linked-list,complexity-theory,nodes,singly-linked-list,Python,Linked List,Complexity Theory,Nodes,Singly Linked List,一个带有两个类的单链表,Node和LinkedList,很容易实现。然而,我的问题是当涉及到只有第一个节点访问的单链表时(没有存储长度,没有最后一个节点访问,并且没有使用虚拟节点)。我无法在网上了解的特殊方法类似于pythons内置的列表操作,复杂性为O(1),如下所示: aa = LinkedList() -- creates empty list aa.first() -- similar to aa[0] aa.rest() -- similar to aa[1:] aa.co
aa = LinkedList() -- creates empty list
aa.first() -- similar to aa[0]
aa.rest() -- similar to aa[1:]
aa.cons(item) -- similar to aa[item:]
[item] + aa -- similar to aa.insert(0, item)
任何形式的引导、帮助和指导都将不胜感激。出于某种原因,如果没有虚拟节点或存储的长度和迭代器,我就无法将Python内置的列表运算符解释到LinkedList中我自己的方法中。看着它,我似乎离它很近,但我所做的或发现的一切似乎都无济于事。多谢各位
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self, newdata):
self.data = newdata
def setNext(self, newnext):
self.next = newnext
def __str__(self):
return str(self.data)
def __repr__(self):
return "Node(%s, %s)" % (repr(self.data), repr(self.next))
def __eq__(self, other):
return self.data == other.data and self.next == other.next
class myList:
def __init__(self):
self.first = Node()
def add(self, data):
newNode = Node() # create a new node
newNode.data = data
newNode.next = self.first # link the new node to the 'previous' node.
self.first = newNode # set the current node to the new one
def first(self):
return self.first.data
def __repr__(self):
plist = []
for i in self:
plist.append(i)
return "LinkedList(%s)" % str(plist)
在没有看到您的代码的情况下,我想我能给出的基本提示是,如果您正在进行基于链表的操作,那么它将涉及大量的迭代。使用像
aa.cons(item)
这样的东西将是低效的,并且基于迭代,因为与基于数组的列表不同,您不能跳转到特定索引处的项
对于以下示例,我假设您的LinkedList
类有一个名为first
的变量,该变量指向列表中的第一项,每个节点都有一个名为next
的变量,该变量指向列表中的下一项,还有一个名为data
的变量,该变量保存该节点上的数据
对于aa.first()。把那个还给我
对于其他方法,需要迭代。这是一个如何循环并打印列表的示例
current = list.first
while current is not None:
print current.data
current = current.next
对于aa.rest()
,必须跳过第一项,然后循环浏览列表的其余部分。要在列表中迈出一步,基本上需要跟踪当前位置并进行迭代。要返回list[1:],我认为最简单的方法是创建一个新的列表,然后进行迭代,将从1开始的所有项添加到末尾
aa.rest()
实际上只是aa.cons(item)
的一个特例。在列表中迭代,直到当前指针到达项
,然后创建一个新列表,其中包含此后的所有内容
从rest()
和cons(…)
返回时,不一定要创建新的列表,这取决于您想要如何实现它。我将留下插页供您考虑
如果一个链接列表
只有一个指向标题的指针
,那么除了添加到列表前面或访问第一项之外,你不会得到O(1),其他所有内容都大约是O(N)
我希望这有点帮助 在没有看到您的代码的情况下,我想我能给出的基本提示是,如果您正在进行基于链表的操作,那么它将涉及大量的迭代。使用像aa.cons(item)
这样的东西将是低效的,并且基于迭代,因为与基于数组的列表不同,您不能跳转到特定索引处的项
对于以下示例,我假设您的LinkedList
类有一个名为first
的变量,该变量指向列表中的第一项,每个节点都有一个名为next
的变量,该变量指向列表中的下一项,还有一个名为data
的变量,该变量保存该节点上的数据
对于aa.first()。把那个还给我
对于其他方法,需要迭代。这是一个如何循环并打印列表的示例
current = list.first
while current is not None:
print current.data
current = current.next
对于aa.rest()
,必须跳过第一项,然后循环浏览列表的其余部分。要在列表中迈出一步,基本上需要跟踪当前位置并进行迭代。要返回list[1:],我认为最简单的方法是创建一个新的列表,然后进行迭代,将从1开始的所有项添加到末尾
aa.rest()
实际上只是aa.cons(item)
的一个特例。在列表中迭代,直到当前指针到达项
,然后创建一个新列表,其中包含此后的所有内容
从rest()
和cons(…)
返回时,不一定要创建新的列表,这取决于您想要如何实现它。我将留下插页供您考虑
如果一个链接列表
只有一个指向标题的指针
,那么除了添加到列表前面或访问第一项之外,你不会得到O(1),其他所有内容都大约是O(N)
我希望这有点帮助 @sgusc发现到目前为止你所拥有的一个真正的大问题:先命名函数
,然后再命名数据属性
。后者最终覆盖前者(因为函数实际上在类中而不是实例中)
解决这个问题会使某些东西接近工作状态。我简化了一些事情,添加了一个小测试驱动程序,并添加了一个\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,它使用一个生成器依次生成每个节点的数据,以便for I in self
(在myList.\uuuu。差异:
--- a/user1337598.py
+++ b/user1337598.py
@@ -1,4 +1,4 @@
-class Node:
+class Node(object):
def __init__(self, data=None, next=None):
self.data = data
self.next = next
@@ -19,27 +19,36 @@ class Node:
return str(self.data)
def __repr__(self):
- return "Node(%s, %s)" % (repr(self.data), repr(self.next))
+ return "Node(%r, %r)" % (self.data, self.next)
def __eq__(self, other):
return self.data == other.data and self.next == other.next
-class myList:
+class myList(object):
def __init__(self):
- self.first = Node()
+ self.first = None
def add(self, data):
- newNode = Node() # create a new node
- newNode.data = data
- newNode.next = self.first # link the new node to the 'previous' node.
+ newNode = Node(data, self.first) # create a new node
self.first = newNode # set the current node to the new one
- def first(self):
+ def getFirst(self):
return self.first.data
+ def __iter__(self):
+ node = self.first
+ while node is not None:
+ yield node.data
+ node = node.next
def __repr__(self):
plist = []
for i in self:
plist.append(i)
return "LinkedList(%s)" % str(plist)
+
+if __name__ == '__main__':
+ lst = myList()
+ lst.add(1)
+ lst.add(2)
+ print repr(lst)
请注意,repr
使用名称LinkedList
,即使类名是myList
。我通常编写我的repr
函数来使用self.\uuuuu class.\uuuuu name.\uuuuu
,例如:
def __repr__(self):
return '%s(%r, %r)' % (self.__class__.__name__, self.item1, self.item2)
这也允许基类\uuuuu repr\uuuuu
为派生类工作(有时需要派生类的一点帮助)。@sgusc发现了迄今为止存在的一个真正的大问题:首先命名函数,然后命名da