【问题标题】:Single Linked List search in PythonPython中的单链表搜索
【发布时间】:2014-04-05 16:50:52
【问题描述】:

我想在链表中搜索一个值/字符并返回该值/字符在链表中的次数。如果我只使用递归而不是尾递归会更容易吗?

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

当我尝试测试它时,我得到了这个:

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'

\

【问题讨论】:

  • 你能发布你的整个测试吗?

标签: python list search linked-list


【解决方案1】:

我不会使用递归,而是使用迭代器模式。这是针对您的问题的一种方法:

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

通过我定义Python special method__iter__,可以按以下方式顺序访问LinkedList 的元素:

l = LinkedList([1, 2, 3, 3, 3, 4, 5])
for value in l:
    print(value)

然后直接实现所需的方法count

请注意,我使用 Python 生成器语法来实现 __iter__,您可以阅读有关生成器和 yield 语句 here 的信息。

【讨论】:

    【解决方案2】:

    跟踪您的代码:

     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
    

    这就是 Traceback 告诉你的。

    编辑:还有两件事:(1)我不确定为什么 count 甚至调用 mkMyList 时似乎您的意图是在函数 args 中将列表 l 传递给它。 (2) 我猜你想把 size-check if 语句放在这个函数的顶部:

    if l.size == 0:
        return c
    

    【讨论】:

      【解决方案3】:

      我看到的问题是count 中的列表从未正确初始化。在mkMyList() 中,head 元素设置为和Empty,它没有next 属性。在count() 中,您只使用mkMyList()。这意味着l.headEmpty,它不可能有next 属性。为了解决这个问题,我建议使用给定的输入实例化列表l

      关于递归的问题:不,在组成尾递归函数和规则递归函数方面几乎没有区别。

      【讨论】:

        猜你喜欢
        • 2016-03-23
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        • 2020-04-15
        • 2019-07-24
        • 1970-01-01
        • 2011-05-17
        • 2020-07-10
        相关资源
        最近更新 更多