约瑟夫环

约瑟夫(Joseph)问题的一种描述是:编号为1,2,3,…,n的n个人按顺时针方向围坐一圈。每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,令其出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新报数,如此下去,直到所有人全部出列为止。试设计一个程序求出出列顺序。

按照出列的顺序打印出各人的编号。

测试数据:

    m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)

C语言写的代码,因为要用到引用,所以建立的是C++

#include <iostream>
#include<malloc.h>

typedef struct lnode{ 
	int n;//个人编号 
	int pwd;//手持密码 
	int length; //链表长度 
	struct lnode *next;
}lnode,*linklist;//定义节点和链表 

linklist listcreat(linklist &l){//创建循环链表 
	l=(linklist)malloc(sizeof(lnode));
	int n,j=1;
	l->length=0;//记录链表长度 
	lnode *p=l;
	int pw;
	printf("输入人数n:\n");
	scanf("%d",&n);
	printf("依次输入每个人所持密码数字:\n");
	while(j<=n)//建立j个节点 
	{
		lnode *s=(lnode*)malloc(sizeof(lnode));
		s->n=j;//申请S节点 
		scanf("%d",&pw);
		s->pwd=pw;
		p->next=s;
		p=s;
		j++;
		l->length++;//链表长度 
	}
	p->next=l->next;//链表循环实现 
	return l;
}

linklist test(linklist &l){
	lnode *p=l;//p寻找目标节点前驱 
	lnode *q;//q指向删除目标节点 
	int a=l->length;
	int temp1,temp2;//1序号,2密码 
	int j=0;
	int m; 
	printf("输入m初始值:\n");
	scanf("%d",&m); 
	while(a>=1)//直到链表长度变成1 
	{
		while(j<m-1)//寻找删除节点前驱 
		{
			p=p->next;//执行后p指目标前驱 
			j++;
		}
		q=p->next;//q指向要删除的节点 
		temp1=q->n;
		temp2=q->pwd;//提取q中数据 
		printf("依次删除序号为%d 所持密码为%d\n",q->n,q->pwd);
		p->next=q->next;//P指向q后链表 
		a--;//长度减一 
		m=q->pwd%a;//除余后,m为新的寻找位序
		free(q);//释放q节点 
		j=0;//寻找新的要删除密码数重置寻找变量为0 
	}
}

int main(int argc, char** argv) {
	linklist l; 
	listcreat(l);//尾插法创建循环链表l 
	test(l);//解决问题功能 
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值