算法导论 14-2 Josephus 排列

n个人排成环,并从1到n编号,给定正整数m,从第一个人开始报数,每次报到m的那个人出列,求人员出列的排列,称为(n,m)-Josephus 排列

 

a) 假定m的常数,找出O(n)的算法完成(n,m)-Josephus排列

最直观的方法,让这n个人组成环形队列,遍历m个结点才能出一个人,(n,m)-Josephus排列需要m*n次遍历,由于m为常数,故此算法为O(n)

 

b) 假定m不是常数,找出O(nlgn)的算法完成(n,m)-Josephus排列

 

(1) 构造n个结点的扩展红黑树,该红黑树的中序遍历为1-n,复杂度为O(n),因为这是有序的队列,所以可以在O(n)时间内先构造n个结点的完全二叉树,最后一层结点标志为红色,其他结点标志为黑色,然后在O(n)时间中序遍历这个红黑树,对每个结点赋值

使用size balanced tree即可,结点内存储当前子树的结点数信息

(2) 开始报数

         第一个出列的序号为m%n,即其在n个结点的次序值为m%n,可以使用lgn的时间获得该结点,删除此结点使用时间为lgn,同时当前结点数为n-1

         某次出列的序号假设为k,出列此人后当前结点数设置为s,则下一次出列的序号可以使用O(1)的时间计算获取,为(k + m) % s,

         所有人出列的时间为lg(n) +lg(n-1) + ... + lg(1),即为O(nlgn)

 

综上两个阶段,此算法的时间复杂度为O(nlgn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值