简体   繁体   English

我将如何在 python 中反转任何给定队列的内容?

[英]How would I reverse the contents of any given queue in python?

I am relatively new to python and am wondering how one would approach reversing a queue.我对 python 比较陌生,想知道如何反转队列。 Now if I understand correctly, a queue is simply a data structure that can be implemented in any language, using a list in python for example.现在,如果我理解正确的话,队列只是一种可以用任何语言实现的数据结构,例如使用 python 中的列表。

So basically if a question asks to reverse a stack or a queue, but since both can be represented using a list, isn't it the same as saying to reverse the contents of the list?所以基本上,如果一个问题要求反转堆栈或队列,但由于两者都可以使用列表表示,这与反转列表的内容不一样吗? I did some research on this topic and found that through using a class and methods, you can implement enqueue, dequeue and isEmpty operations.我对这个主题做了一些研究,发现通过使用一个类和方法,你可以实现入队、出队和 isEmpty 操作。

class Queue:

    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

So if I were asked to reverse the contents of a queue stack for example, does that mean I have to reverse the contents of the list by using only the above methods?例如,如果我被要求反转队列堆栈的内容,这是否意味着我必须仅使用上述方法反转列表的内容? (by only removing items at the front of the list, and adding items at the back of list) (仅删除列表前面的项目,并在列表后面添加项目)

You can use an auxiliar stack to reverse the elements of your Queue.您可以使用辅助堆栈来反转队列的元素。

Basically, you will stack every element of your Queue until it becomes empty.基本上,您将堆叠队列的每个元素,直到它变空。 Then you pop each element of your stack and enqueue it until your stack is empty.然后弹出堆栈中的每个元素并将其排入队列,直到堆栈为空。

# suppose your have a Queue my_queue
aux_stack = Stack()
while not my_queue.isEmpty():
    aux_stack.push(my_queue.dequeue())

while not aux_stack.isEmpty():
    my_queue.enqueue(aux_stack.pop())

No stack needed!不需要堆栈!

  • Note that you need to be able to find the length of the queue.请注意,您需要能够找到队列的长度。 We can do this with an auxiliary queue, by popping and counting, and then replacing the items.我们可以用一个辅助队列来做到这一点,通过弹出和计数,然后替换项目。

  • Note that you can rotate a queue trivially with repeated pop - push pairs.请注意,您可以使用重复的pop - push对简单地旋转队列。

  • Note you can switch indices m and n as so:请注意,您可以像这样切换索引mn

     Have [ 1 2 3 ... m-1 m m+1 ... n-1 n n+1 ... x ] Want [ 1 2 3 ... m-1 n m+1 ... n-1 m n+1 ... x ] Rotate to n [ n+1 ... x 1 2 3 ... m-1 m m+1 ... n-1 n ] Pop into temporary storage [ n+1 ... x 1 2 3 ... m-1 m m+1 ... n-1 ] t = n Rotate to m [ m+1 ... n-1 n+1 ... x 1 2 3 ... m-1 m ] t = n Push from temporary storage [ n m+1 ... n-1 n+1 ... x 1 2 3 ... m-1 m ] Pop into temporary storage [ n m+1 ... n-1 n+1 ... x 1 2 3 ... m-1 ] t = m Rotate to n-1 [ n+1 ... x 1 2 3 ... m-1 n m+1 ... n-1 ] t = m Push from temporary storage [ n+1 ... x 1 2 3 ... m-1 n m+1 ... n-1 m ] Rotate to x [ 1 2 3 ... m-1 n m+1 ... n-1 m n+1 ... x ]

    So we can swap positions m and n in O(len(queue)) .所以我们可以在O(len(queue))交换位置mn

  • Repeatedly swap the n th and len(queue)-n th items until n ≥ len(queue)-n .重复交换第nlen(queue)-n项,直到n ≥ len(queue)-n


So here it is:所以这里是:

class Queue:

    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    # For visualisation
    def __repr__(self):
        return repr(self.items)

Length-finding routine:测长程序:

def queue_length(queue):
    length = 0
    auxillary = Queue()

    while not queue.isEmpty():
        length += 1
        auxillary.enqueue(queue.dequeue())

    while not auxillary.isEmpty():
        queue.enqueue(auxillary.dequeue())

    return length

Rotating routine:轮换程序:

def rotate(queue, n):
    for _ in range(n):
        queue.enqueue(queue.dequeue())

Swapping routine:交换例程:

def swap(queue, m, n):
    length = queue_length(queue)

    # Make sure m ≤ n
    if m > n:
        m, n = n, m

    # Rotate to n
    rotate(queue, length-n-1)

    # Pop into temporary storage
    temp = queue.dequeue()

    # Rotate to m
    rotate(queue, n-m-1)

    # Swap
    queue.enqueue(temp)
    temp = queue.dequeue()

    # Rotate to where n was
    rotate(queue, m-n-1+length)

    # Push back
    queue.enqueue(temp)

    # Rotate to start
    rotate(queue, n)

Reversing routine:倒车例程:

def reverse(queue):
    left = 0
    right = queue_length(queue)-1

    while left < right:
        swap(queue, left, right)
        left += 1
        right -= 1

To test:去测试:

queue = Queue()
for i in reversed(range(20)):
    queue.enqueue(i)

queue
#>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

reverse(queue)
queue
#>>> [19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Note that this can be made faster by finding different swaps that themselves are simpler;请注意,可以通过查找本身更简单的不同交换来加快速度;

  [ a b c d e f g ]
→ [ b c d e f g a ]
→ [ c d e f g b a ]
→ [ d e f g c b a ]
→ [ e f g d c b a ]
→ [ f g e d c b a ]
→ [ g f e d c b a ]

so we have the routine "push index 0 to index n ".所以我们有例程“将索引0推送到索引n ”。

This is just这只是

def shift_head(queue, n):
    length = queue_length(queue)

    # Rotate head to end and pop
    rotate(queue, length-1)
    temp = queue.dequeue()

    # Insert in position n
    rotate(queue, length-n-1)
    queue.enqueue(temp)

    # Rotate back
    rotate(queue, n)

giving给予

def quickreverse(queue):
    push_to = queue_length(queue)

    while push_to:
        shift_head(queue, push_to)
        push_to -= 1

which works:哪个有效:

queue
#>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

quickreverse(queue)
queue
#>>> [19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

A Simple way using another queue使用另一个队列的简单方法

queue = [] # queue
queue.append(1) # adding items
queue.append(2)
queue.append(3)
print(queue)   #original queue

queue_2 = []
for i in range(0,len(queue)):
    queue_2.append(queue.pop())
print(queue_2) # reversed queue
  1. create an empty queue using a python list使用 python 列表创建一个空队列
  2. append items to list将项目附加到列表
  3. create another empty queue.创建另一个空队列。

4.Using a for loop pop the values from 1st queue to the second one. 4.使用 for 循环将值从第一个队列弹出到第二个队列。

5.Done!!! 5.完成!!!

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

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