繁体   English   中英

一种在python中以倒序/倒序打印链表的方法

[英]A method to print linked list in reverse/backward order in python

我正在编写一个名为 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()
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 所以我们移动到代码的第二行,这是对 head.next 的第一次递归调用,即 2。我们再次看到这个新的“head”不等于 null,因此我们进行了第二次递归调用,这次传递了包含 3 的节点。我们看到这个新的“head”不等于 null,所以我们对 head.next 进行第三次递归调用,在这种情况下它是 null。 所以我们回来了,因为我们达到了我们的基本情况。 现在我们又回到了第二个递归调用中,我们移到递归调用之后的代码行,即打印语句。 我们打印 3。由于这个递归调用现在已经完成,我们回到第一个递归调用,并打印 2。最后,我们回到最初的函数调用,我们打印 1。因此,成功地反向打印我们的链表命令。

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

这可能是您的代码草稿:

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 中看起来很混乱。

我希望您的问题是由于没有有效的方法来向后迭代单链表。

我通过使用一些魔术方法(又名dunder方法)稍微增强了您的代码:名称(通常)以双下划线开头和结尾的方法。 您可以在特殊方法名称下的文档中阅读有关它们的信息。

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

我已将您的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

您可以通过使用两个循环来实现它。 一个用于循环整个列表,另一个用于转到与主循环相关的特定节点并打印它。 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM