【问题标题】:How to print elements in Python linked list alternatively left and right from middle?如何从中间左右交替打印Python链表中的元素?
【发布时间】:2019-07-15 12:00:47
【问题描述】:

我在 Python 中有这样的链表

class Node:
    def __init__(self, dataval=None):
        self.dataval = dataval
        self.nextval = None

class SInglylInkedList:
    def __init__(self):
        self.headval = None

lst = SInglylInkedList()
lst.headval = Node("Jan")
e2 = Node("Feb")
e3 = Node("Mar")
e4 = Node("Apr")
e5 = Node("May")
e6 = Node("June")
e7 = Node("July")
e8 = Node("Aug")
e9 = Node("Sep")
e10 = Node("Oct")
e11 = Node("Nov")
e12 = Node("Dec")

lst.headval.nextval = e2

e2.nextval = e3
e3.nextval = e4
e4.nextval = e5
e5.nextval = e6
e6.nextval = e7
e7.nextval = e8
e8.nextval = e9
e9.nextval = e10
e10.nextval = e11
e11.nextval = e12

现在这个方法会直接打印元素

def listprint(self):
    printval = self.headval
    while printval is not None:
        print (printval.dataval)
        printval = printval.nextval

一月二月三月四月五月六月→ 七月 八月 九月 十月 十一月 十二月

我想像这样从中间左右交替打印元素

六月七月五月八月四月九月→ 三月 10 月 2 月 11 月 1 月 12 月

帮我写打印方法

【问题讨论】:

    标签: python data-structures linked-list singly-linked-list


    【解决方案1】:

    由于您没有在该问题上显示您自己的代码,因此我将仅提供一些关于算法的想法。 (您显示代码以设置链接列表并照常打印它,但没有针对实际问题尝试代码。)如果您要向您显示一些代码,请先做更多工作并在您的问题中显示它。

    一种解决方案是将链表转换为标准 Python list。然后,您找到此列表的长度,然后生成所需的索引,访问与这些索引关联的值。在您的特定示例中,列表的长度为12,因此您按以下顺序生成这些索引:

    5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11
    

    我希望你能看到那里的模式。

    另一种避免标准列表的方法是构建反向链表。您不需要反转整个链表,只需反转前半部分即可。在我上面生成的那些索引中,您可以看到子列表5, 4, 3, 2, 1, 0,它是列表的前半部分。您可以构建该列表,然后交替使用原始列表的前半部分和后半部分进行打印。

    但这种方式可能仍会使用内存来复制一半的列表。您可以通过使用堆栈或递归来以相反的顺序访问列表的前半部分来避免该内存。这仍然使用内存,但仅用于指向列表项的指针。 (我的意思是基层内存中的指针——Python 隐藏了实际的指针。)

    如果您想了解更多细节,请展示更多您自己的作品,我很乐意用文字和代码进行更多解释。

    【讨论】:

      【解决方案2】:

      我认为你的问题是要写

      lst.headval.nextval = e2 instead of lst.headval.nextval = e12,对吗?

      一个快速而肮脏的解决方案是

      def listprint_answer(self):
          topval = self
          bottomval = self.nextval
          while bottomval.nextval is not None:
             newtopval=lst.headval
             while newtopval.nextval is not topval:
                 newtopval=newtopval.nextval
             print(topval.dataval)
             topval=newtopval
             print(bottomval.dataval)
             bottomval=bottomval.nextval
          print(lst.headval.dataval)
          print(bottomval.dataval)
      listprint_answer(e6)
      

      【讨论】:

        【解决方案3】:

        冒昧地重新实现了 SinglyLinkedList 类,但想法是一样的。要生成交替模式 - 当您迭代节点时 - 您可以使用堆栈来跟踪节点,直到原始链接列表的中间。一旦你在中间,你就不再将节点压入堆栈,你只会从堆栈中弹出并追加到你的新链表,同时也追加你正在查看的当前节点。

        class Node:
        
            def __init__(self, value, left=None, right=None):
                self.value = value
                self.left = left
                self.right = right
        
        class SinglyLinkedListIterator:
        
            def __init__(self, node):
                self.node = node
        
            def __iter__(self):
                return self
        
            def __next__(self):
                if self.node is None:
                    raise StopIteration
                node, self.node = self.node, self.node.right
                return node
        
        class SinglyLinkedList:
        
            def __init__(self):
                self.head = None
                self.tail = self.head
                self.length = 0
        
            def __len__(self):
                return self.length
        
            def __iter__(self):
                return SinglyLinkedListIterator(self.head)
        
            def append(self, *values):
                for value in values:
                    node = Node(value)
                    if self.head is None:
                        self.head = node
                    else:
                        self.tail.right = node
                    self.length += 1
                    self.tail = node
        
            def display(self):
                for node in iter(self):
                    print(node.value, end=[" -> ", "\n"][node is self.tail])
        
            @staticmethod
            def to_alternate(linked_list):
                linked_list_alt = SinglyLinkedList()
                node_stack = []
                length = len(linked_list)
                for index, node in enumerate(linked_list):
                    if index <= (length // 2) - [1, 0][length%2]:
                        node_stack.append(node)
                    else:
                        linked_list_alt.append(node_stack.pop().value)
                        linked_list_alt.append(node.value)
                while node_stack:
                    linked_list_alt.append(node_stack.pop().value)
                return linked_list_alt
        
        def main():
        
            linked_list = SinglyLinkedList()
        
            months = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"]
            linked_list.append(*months)
            linked_list.display()
        
            SinglyLinkedList.to_alternate(linked_list).display()
        
            return 0
        
        
        if __name__ == "__main__":
            import sys
            sys.exit(main())
        

        输出:

        Jan -> Feb -> Mar -> Apr -> May -> June -> July -> Aug -> Sep -> Oct -> Nov -> Dec
        June -> July -> May -> Aug -> Apr -> Sep -> Mar -> Oct -> Feb -> Nov -> Jan -> Dec
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-22
          • 1970-01-01
          • 2017-02-21
          相关资源
          最近更新 更多