📄 4(ok).c
字号:
#include "stdio.h"
#include "malloc.h"
typedef struct node
{
int code;
struct node *next;
}Joeph;
Joeph *CreatlistR()
{
Joeph *J,*S,*R;
char ch;
J=(Joeph *)malloc(sizeof(Joeph));
J->next=NULL;
R=J;
printf("请输入数据,'0'表示输入结束:\n");
while (1)
{
while(1)
{
scanf("%d", &ch);
if (ch == 0x0A)
continue;
else
break;
}
if (ch==0)
break;
S=(Joeph *)malloc(sizeof(Joeph));
S->code=ch;
S->next=NULL;
R->next=S;
R=S;//尾指针后移
}
R->next=J->next;
return J;
}
/*问题描述]
约瑟夫(Joeph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
解决问题的核心步骤:
1.建立一个具有n个链结点,无头结点的循环链表
2.确定第1个报数人的位置
3.不断地从链表中删除链结点,直到链表为空
*/
void JOSPHUS()
{
Joeph *p,*r,*J;
int i,m,k;//k为开始报数人的序号,m为报数上限值
printf("输入报数上限值:\n");
while(1)
{
scanf("%d", &m);
if (m == 0x0A)
continue;
else
break;
}
printf("第一个喊数的人的序号:\n");
while(1)
{
scanf("%d", &k);
if (k == 0x0A)
continue;
else
break;
}
/* p为当前结点 , r为辅助结点,指向p的前驱结点 list为头节点*/
/*建立循环链表*/
printf("创建Joeph环:\n");
J=CreatlistR();
/*把指针定位到第一个报数的人*/
p=J;
for(i=0;i<k;i++)
p=p->next;
/*循环地删除队列结点*/
while(p->next!=p)
{
for(i=0;i<m-1;i++)
{
r=p;
p=p->next;
}
r->next=p->next; //删除喊道m的节点
printf("被删除的元素:%4d\n",p->code);
free(p);
p=r->next;
}
printf("被删除的元素:%4d\n",p->code);//最后一个被删除的数
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void main()
{
printf("=============Joeph环小程序===========\n");
JOSPHUS();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -