python实现队列(含约瑟夫环)

python对队列的实现

什么是队列?

  1. 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
  2. 队列的特性:先进先出(FIFO,First In First Out),它就像在超市买完东西排队结账一样,先排的人先结账走人
    在这里插入图片描述

用python实现队列(version 3.7.2)

  1. python最直观的特点就是简洁,因此实现一个简单的队列只需几行代码
  2. 以列表尾部作为队头,列表首部作为队尾
  3. insert(0)的复杂度是O(n),pop()的复杂度是O(1),append()的复杂度是O(1),pop(0)的复杂度是O(n) 可以自己选择列表两端作为队列头或尾,时间复杂度是一样的
  4. 关于为什么复杂度是O(1),O(n)可以看我另一篇文章
# 队列
class Queue:
	# 初始化一个空列表
    def __init__(self):
        self.items = []
	# 是否空队列
    def isEmpty(self):
        return self.items == []
	# 入队列
    def enquque(self, item):
        self.items.insert(0, item)
	# 出队列
    def dequeue(self):
        return self.items.pop()
	# 队列当前容量
    def size(self):
        return len(self.items)
  1. 这里没有限制队列的容量,可以初始化一个size作为队列容量(这里只简单提一下)

接着用上面的队列来实现约瑟夫环问题

  1. 约瑟夫环问题来源:据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决。Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。(摘自百度百科)
  2. 这类型问题用队列或链表都很容易解决
  3. 比如有30个人,从头开始循环报数,每次报到5的人被淘汰(说死亡太血腥了…),要求列出淘汰顺序
  4. 先把所有人排成一队(放入一个队列中),从头报数,报到5的自动出列(淘汰),报到其他数的人走到队伍最后边接着排队,直到队伍的人全部出列
  5. 逻辑很简单,下边是一个简单的实现
from Queue import *
def josepRing(nums, length):
    q = Queue()
    for i in nums:
        q.enquque(i)

    while not q.isEmpty():
        for i in range(length-1):
            cur = q.dequeue()
            # 重新入队列
            q.enquque(cur)
        # 淘汰
        print(q.dequeue())

# 可以自己控制参数
josepRing([1, 2, 3, 4, 5], 5)

如有错误还望指出
允许转载但请注明出处

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值