python中带有特殊方法的单链表,卡住了

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

一个带有两个类的单链表,Node和LinkedList,很容易实现。然而,我的问题是当涉及到只有第一个节点访问的单链表时(没有存储长度,没有最后一个节点访问,并且没有使用虚拟节点)。我无法在网上了解的特殊方法类似于pythons内置的列表操作,复杂性为O(1),如下所示:

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