一种在python中以反向/反向顺序打印链表的方法

时间:2015-12-14 10:50:29

标签: python linked-list

我正在写一个名为LList的类,在课堂上我定义了几种方法。我遇到了编写一个以反向顺序打印链表的方法的问题。

class Node(object):
    def __init__(self, data=None, nextNode=None):
        self.data = data
        self.nextNode = nextNode

class LList(object):

    def __init__(self, head=None):
        self.head = head
        self.size = 0

    def insert(self, node):

        if not self.head:
            self.head = node
            self.size += 1
        else:
            # set new nodes pointer to old head
            node.nextNode = self.head
            # reset head to new node
            self.head = node
            self.size +=1

    def getSize(self):
        return self.size

    def printLL(self):
        mynode = self.head
        c = 0
        while mynode:
            c += 1
            print(mynode.data, c)
            mynode = mynode.nextNode

#a method for class that prints list backwards.       
    def reverse(self):


#main program

    MyList = LList()
    MyList.insert(Node("NJ"))
    MyList.insert(Node("NR"))
    MyList.insert(Node("OH"))

    # Use my print method
    MyList.printLL()
    #print in reverse
    MyList.reverse()

4 个答案:

答案 0 :(得分:3)

class Node(object):

          def __init__(self, data=None, next_node=None):
              self.data = data
              self.next = next_node

       def ReversePrint(head):
           if head == None:
              return
           else:
             ReversePrint(head.next)
             print(head.data)

让我们举个例子链接列表:1-> 2-> 3 遍历代码,函数ReversePrint被赋予一个链接到我们的链表的头部,它是1.我们看到头不等于null所以我们移动到代码的第二行,这是第一个递归调用to head.next,这是2.再次,我们看到这个新的" head"不等于null,所以我们做第二次递归调用,这次传递包含3的节点。我们看到这个新的" head"不等于null,所以我们在head.next上进行第三次递归调用,在这种情况下为null。所以我们回来了,因为我们遇到了基础案例。我们现在回到第二次递归调用,然后移动到递归调用之后的代码行,即print语句。我们打印3.由于这个递归调用现在已经完成,我们将回到第一个递归调用,然后打印2.最后,我们回到初始函数调用,然后打印1.因此,成功打印我们的链接列表订购。

答案 1 :(得分:2)

好吧,除非你有一个双链表,你最好的选择是遍历整个链表,保存内存中的所有内容,然后打印出来。

这可能是您的代码草稿:

def print_reversed(self):

    node = self.head
    values = []
    while node:
        values.append(node.data)
        node = node.nextNode

    for value in reversed(values):
        print(value)

这以某种方式打败了链表的目的。你也可以递归地做到这一点,但这看起来会很混乱IMO。

答案 2 :(得分:2)

我希望您的问题是因为没有有效的方法可以在单链列表上向后迭代。

我通过使用一些神奇的方法(又名dunder方法)略微增强了你的代码:名称(通常)以双下划线开头和结尾的方法。您可以在Special method names下的文档中了解它们。

当对象传递给__str__内置函数时,会调用对象的str方法(当您尝试打印对象时会隐式发生这种情况)。如果对象没有__str__方法,则调用其__repr__方法;通常最好定义这两种方法中的至少一种,否则当您尝试打印对象时,将调用从通用__repr__继承的默认object方法。

我已将您的getSize方法更改为__len__,当对象传递给len内置函数时会调用该方法。

对象的__iter__方法在传递给iter内置函数时会被调用,无论是显式传递还是当您尝试在某种for循环中迭代对象时,或者当您将其传递给list或类似的构造函数时。它通常与__next__方法结合使用,该方法(不幸的是)在Python 2中命名为next。当一个对象具有这些方法时,以各种方式迭代它是相对容易的。

要进行反向打印,我们可以简单地将实例传递给list,并将结果列表传递给reversed,它返回一个迭代器,该迭代器在其列表参数上向后迭代。

以下代码是为Python 2编写的;对于Python 3,将next方法更改为__next__

class Node(object):
    def __init__(self, data=None, nextNode=None):
        self.data = data
        self.nextNode = nextNode

    def __str__(self):
        return str(self.data)

class LList(object):
    def __init__(self):
        self.head = None
        self.current = None
        self.size = 0

    def insert(self, node):
        if self.head is not None:
            # set new node's pointer to old head
            node.nextNode = self.head
        self.head = node
        self.size += 1

    def __len__(self):
        return self.size

    def __iter__(self):
        self.current = self.head
        return self

    def next(self):
        current = self.current
        if current is None:
            raise StopIteration
        else:
            self.current = current.nextNode
            return current

    def printLL(self):
        for i, node in enumerate(self, 1):
            print(node, i)

    # print the list backwards
    def reverse_print(self):
        c = len(self)
        for node in reversed(list(self)):
            print(node, c)
            c -= 1


# main program
mylist = LList()
mylist.insert(Node("NJ"))
mylist.insert(Node("NR"))
mylist.insert(Node("OH"))

print(len(mylist))

# print forwards
mylist.printLL()

#print the nodes using a list comprehension
print([str(node) for node in mylist])

#print in reverse
mylist.reverse_print()

<强>输出

3
OH 1
NR 2
NJ 3
['OH', 'NR', 'NJ']
NJ 3
NR 2
OH 1

答案 3 :(得分:0)

您可以通过使用两个循环来实现。一个用于循环整个列表,另一个用于相对于主循环转到特定节点并进行打印。 Count()返回节点数。当count的值为0时,节点循环由于(self.Count()-count)在最后一个节点处停止并进行打印。就像它向后退。

def reverse(self):
    for count in range(self.Count()+1):
       
        iteration = 0       
        printval = self.head

        while printval != None:
            if iteration == (self.Count() - count):  
                break
            printval = printval.next
            iteration = iteration + 1
        print(printval.name)