循环链表报数问题,n个人编号分别为1,2,3,……n,从第k个编号开始数1,2到m个然后删除第m个人,然后下 一个人再从1开始数数到第m个,然后再删除m人

#include<iostream>
#include<stdio.h>
using namespace std;
//循环链表报数问题,n个人编号分别为1,2,3,……n,从第k个编号开始数1,2到m个然后删除第m个人,然后下
//一个人再从1开始数数到第m个,然后再删除m人
struct Lnode
{
int data;
Lnode *link;
};
void josephus(int n,int k,int m)
{
//n为总人数,k为第一个开始报数的人,m为出列者喊道的数
/*p为当前节点,r为辅助节点,指向p的的前驱节点,list为头节点*/
/*建立循环链表*/
Lnode *p,*r,*curr,*list;
p=(Lnode*)malloc(sizeof(Lnode));
p->data=1;
p->link=p;
curr=p;
for(int i=2;i<=n;i++)
{
Lnode *ln=(Lnode*)malloc(sizeof(Lnode));
ln->data=i;
ln->link=curr->link;
curr->link=ln;
curr=curr->link;
}
/*把当前指针移动到第一个报数的人*/
r=curr;
while(r->data!=k)r=r->link;


while(n--)
{
for(int i=1;i<m-1;i++)
r=r->link;//当数到m-1的时候
cout<<r->link->data<<endl;
p=r->link;
r->link=r->link->link;
free(p);
p=r=r->link;


}
}
void main()
{
josephus(9,1,3);

system("pause");
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个利用队列实现的约瑟夫环问题:已知n个人(以编号1,2,3……n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数到m的那个人出列;他的下一个人又从1开始报数到m的那个人又出列;依次类推,直到剩余最后一个人。根据编号为k的人开始报数,求出最后一个出列的人的编号。 针对这个问题,可以建立一个初始序列为1~n的队列,然后依次按规则将队列首端的字移至队列尾端,直到队列中只剩下最后一个字为止,即为最后一个出列的人的编号。 ### 回答2: 这道题目可以通过队列来实现,可以按照以下步骤进行: 1. 将所有人的编号加入队列中。 2. 从队列中弹出第k个人,将其从队列中删除,并将其保存到一个结果列表中。 3. 将队列中的所有人的编号向后移动k-1个位置,使得下一个出圈的人成为队首。 4. 重复步骤2和步骤3,直到队列中只剩下一个人为止。 具体实现时,我们可以用Python语言来实现,代码如下: ```python def josephus(n, k): queue = list(range(1, n+1)) result = [] while queue: # 第k个人出圈 index = (k-1) % len(queue) result.append(queue.pop(index)) # 向后移动k-1个位置 queue = queue[index:] + queue[:index] return result ``` 其中,n表示总人,k表示开始报数的人的编号。在每一次循环中,我们先找到第k个人,将其从队列中删除并添加到结果列表中,然后向后移动k-1个位置,使得下一个出圈的人成为队首。最后,返回结果列表即可。 这个算法的时间复杂度为O(n^2),因为每次需要移动k-1个位置,总共需要移动n-1次,所以总共需要执行n(n-1)次。如果使用双向循环链表据结构,可以将移动操作的时间复杂度优化到O(1),从而实现更快的算法。 ### 回答3: 利用队列实现约瑟夫环问题非常简单,我们只需要定义一个队列,将所有的人依次加入到队列中,并依次出队即可。 具体实现步骤如下: 1.定义一个空队列,并将所有的人依次加入到队列中。 2.定义一个器变量count,初始化为1,表示从1开始报数。 3.定义一个循环,当队列的长度大于1时,就一直进行循环,直到只有一个人留下。 4.在循环中,每次从队列中出队一个人,然后将count加1。 5.如果count等于k,说明当前这个人需要出圈,直接舍弃不加入队列。 6.否则,将这个人加入到队列尾部,继续循环。 7.重复步骤4-6,直到只有一个人留下,那么这个人就是最后的幸存者。 代码实现如下: def josephus(n, k): # 定义一个空队列,并将所有的人依次加入到队列中 queue = [i for i in range(1, n+1)] # 定义一个器变量count,初始化为1 count = 1 # 循环队列,直到只有一个人留下 while len(queue) > 1: # 从队列中出队一个人 person = queue.pop(0) # 将count加1 count += 1 # 如果count等于k,说明当前这个人需要出圈 if count == k: count = 1 continue # 否则,将这个人加入到队列尾部 queue.append(person) # 最后剩下的那个人就是幸存者 return queue[0] # 测试 print(josephus(10, 3)) # 输出4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值