【问题标题】:Linked Lists Python 2.7链表 Python 2.7
【发布时间】:2012-03-13 17:39:32
【问题描述】:

我在不使用类的情况下尝试实现链接列表时遇到了麻烦(我们的课程中还没有),而谷歌根本没有帮助。每个链表示例都使用了我没有涉及的类。我可以创建一个将值添加到链表开头的链表,但是我不知道如何遍历列表并在特定节点之后添加值。任何帮助,将不胜感激。对我来说最难的部分是弄清楚如何遍历列表。

def addValue(linkedSet, value):
    """
    Adds a new element to a set.
    Parameters:
        the set to be changed (address of the first node)
        the new value to add to the set
    Return result: pointer to the head of the modified set.  This is
        usually the same as the linkedSet parameter, unless the value
        added is less than any value already in the set.

    If the value is already in the set, return the set unchanged.
    This is not an error.
    """
    newNode={}
    newNode['data']=value
    node=linkedSet
    if linkedSet==None:
        newNode['next']=None
        return newNode
    if member(linkedSet,value)==True:
        return linkedSet
    elif linkedSet['next']==None:
        newNode['next']=None
        linkedSet['next']=newNode
    elif linkedSet['next']!=None:
        return linkedSet

【问题讨论】:

  • 你是在实现像列表一样的链表,还是像集合一样的链表?您的问题似乎表明前者,但addValue 上的文档字符串似乎表明后者。
  • 你是完全不允许使用类还是对它们不熟悉?
  • 使用var is Nonevar is not None代替var==Nonevar!=None
  • 考虑到课程是学期后期的话题,我怀疑我的教授是否可以使用课程。
  • 你的linkedSet是如何实现的?

标签: python list linked-list


【解决方案1】:

就像我认为您的 addValue() 函数可能看起来像的大致轮廓......

def addValue(linkedSet, value):

    newNode={
        'data': value,
        'next': None
    }

    # if linkedSet is None, then you can just return this newNode

    # if linkedSet isnt None...
        # if linkedSets next is None, then it should just point to this newNode 
        # (append)

        # otherwise, you should set its current next to the next of this newnode,
        # and then set its next to this newNode (insert)

这是一个通用链表。您似乎在暗示您的版本是一个更专业的版本,它维护一个值排序,并且总是希望通过列表的头节点。你的需要不断循环每个“下一个”,直到找到一个值大于当前值的值,然后通过围绕以下(可能是前一个)元素的“下一个”引用移动来插入自己。

【讨论】:

    【解决方案2】:

    unless the value added is less than any value already in the set 听起来这个列表应该是排序的。因此,您遍历列表,找到大于您的值的第一个项目并将其拼接在那里。

    您通过跟踪当前节点来遍历列表:

    def addValue(linkedSet, value):
    
        newNode={}
        newNode['data']=value
        newNode['next'] = None
    
        #traverse list
        current = linkedSet
        while True: 
            if current['value'] == value: 
                return linkedSet # it was already in that list
    
            if current['value'] > value:
                # new node is the new head
                newNode['next'] = linkedSet
                return newNode # new head
    
            if current['next'] is None:
                # new tail
                current['next'] = new_node
                return linkedSet
    
            if current['next']['value'] > value:
                # new node belongs here, splice it in
                next_node = current['next']
                current['next'] = newNode
                newNode['next'] = next_node
                return linkedSet
    
            # didnt return so far, try the next element:
            current = current['next']
    

    【讨论】:

    • 稍加修改后它就可以工作了,我会花点时间看看它为什么会工作。非常感谢。
    • 我不明白的是代码的拼接部分是如何影响linkedSet的。当您返回linkedSet时,您在技术上不是返回原始列表吗?
    • 他在 4 个案例中返回 linkedSet 3 个的原因是因为根据您的描述,它将作为链表的开头传递。他唯一没有返回原始值的地方是 newNode 成为新的头,所以它被返回了。
    • @NicholasDavison:linkedSet 只是列表的第一个元素。不要将其与列表混淆。链表本身不是一个对象,它仅在您遍历节点之间的链接时隐式存在。因此,当我们更改 current['next'] = newNode 中的一个链接时,它会更改列表,即使我们仍然有相同的第一个元素。
    【解决方案3】:

    使用字典作为链表描述符怎么样? 比如:

    linkedSet = {'first':firstNode, 'last':lastNode}
    

    那么当你需要遍历时,你总是可以从第一个节点开始, 当您需要添加时,您就有了结束节点。

    【讨论】:

    • 如果我想在不是第一个或最后一个的两个节点之间添加一个值怎么办?
    • 这将需要两个对象来维护“列表”。如果你建议linkedSet是一个节点指针,并且它也包含值,那么这不是一个双链表吗?
    • 比您必须遍历要插入值的节点,将新节点链接到下一个节点并将旧节点链接到新节点。 @jdi:linkedSet 将持有对第一个节点的引用,node 将持有一个值和对下一个节点的引用,依此类推,直到结束节点。不放弃双链表结论...
    • 您仍然需要维护linkedSet“元”对象和给定的数据节点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多