[英]Single Linked List search in Python
I want to search a value/character in a linked list and return the number of times the value/character is in the linked list. 我想在链接列表中搜索值/字符并返回值/字符在链接列表中的次数。 Also would it be easier if I just used recursion instead of tail recursion?
如果我仅使用递归而不是尾部递归,还会更容易吗?
class MyList():
__slots__=('head','size')
class Empty():
__slots__=()
class NonEmpty():
__slots__=('data','next')
def mkMyList():
lst = MyList()
lst.head = mkEmpty()
lst.size = 0
return lst
def mkEmpty():
return Empty()
def mkNonEmpty(data,lst):
node = NonEmpty()
node.data = data
node.next = lst
return node
def count(l, value, c = 0):
l = mkMyList()
if l.head != value:
l.head = l.head.next
if l.head == value:
return count(l.head.next, value, c + 1)
if l.size == 0:
return c
When I try to test it, I get this: 当我尝试对其进行测试时,我得到了:
count(s,'s',c= 0)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
count(s,'s',c= 0)
File "C:\Users\Qasim\Desktop\Linked Lists.py", line 30, in count
l.head = l.head.next
AttributeError: 'Empty' object has no attribute 'next'
\\ \\
Rather than use recursion, I would use the iterator pattern. 我将使用迭代器模式,而不是使用递归。 Here is one way to do it in the context of your problem:
这是解决您的问题的一种方法:
class LinkedList(object):
class Node(object):
__slots__ = ('prev', 'next', 'value')
def __init__(self, prev=None, next=None, value=None):
self.prev = prev
self.next = next
self.value = value
def __init__(self, iterable=[]):
self.head = LinkedList.Node() # dummy node
self.tail = self.head
self.size = 0
for item in iterable:
self.append(item)
def __iter__(self):
current = self.head
while True:
if current.next is not None:
current = current.next
yield current.value
else:
raise StopIteration
def append(self, value):
self.tail.next = LinkedList.Node(prev=self.tail, value=value)
self.tail = self.tail.next
self.size += 1
def pop(self):
if self.size > 0:
value = self.tail.value
self.tail = self.tail.prev
self.tail.next = None
self.size -= 1
return value
else:
raise IndexError('pop from empty list')
def count(self, value):
cumsum = 0
for item in self:
if item == value:
cumsum += 1
return cumsum
By my defining a Python special method __iter__
, one can sequentially access the elements of a LinkedList
in the following manner: 通过定义Python特殊方法
__iter__
,可以按以下方式顺序访问LinkedList
的元素:
l = LinkedList([1, 2, 3, 3, 3, 4, 5])
for value in l:
print(value)
which then makes the desired method count
straight-forward to implement. 然后使所需的方法直接
count
即可实施。
Note that I have used the Python generator syntax to implement __iter__
, you can read about generators and the yield
statement here . 请注意,我已经使用Python生成器语法实现
__iter__
,您可以在此处阅读有关生成器和yield
语句的信息 。
Tracing your code: 跟踪代码:
l = mkMyList() # => head = Empty()
if l.head != value: # True since head is Empty()
l.head = l.head.next # Empty does not have a ".next" attribute
This is what the Traceback is telling you. 这就是Traceback告诉您的。
EDIT: Two more things: (1) I'm not sure why count is even calling mkMyList when it seems your intent is to pass it the list, l, in the function args. 编辑:还有两件事:(1)当您的意图是在函数args中将其传递给列表l时,我不确定为什么count甚至调用mkMyList。 (2) I'm guessing you want to put the size-check if statement at the top of this function:
(2)我猜您想将size-check if语句放在此函数的顶部:
if l.size == 0:
return c
The issue I see is that the list in count
is never initialized properly. 我看到的问题是,
count
列表从未正确初始化。 In mkMyList()
, the head
element is set to and Empty
, which has no next
attribute. 在
mkMyList()
, head
元素设置为和Empty
,没有next
属性。 In count()
, you only use mkMyList()
. 在
count()
,仅使用mkMyList()
。 This means that l.head
is an Empty
, and there's no way it could have a next
attribute. 这意味着
l.head
是Empty
,并且不可能拥有next
属性。 To fix this, I would recommend instantiating the list l
using the given input. 为了解决这个问题,我建议使用给定的输入实例化列表
l
。
With regards to the question about recursion: no, there is very little difference in terms of composing a tail recursive function versus a regularly recursive function. 关于递归问题:不,在组成尾递归函数和规则递归函数方面几乎没有什么区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.