/*2018.9.26 数据结构作业 约瑟夫问题*/
/*问题描述:有n个人,编号为1,2,…, n,站成一圈, 每次第m个将会被处决,
直到只剩下一个人。约瑟夫通过给出m来决定赦免其中的一个人。
例如当n=6,m=5时,5,4,6,2,3将会被依次处决,而1将会幸免 */
/*约瑟夫环(约瑟夫问题): 是
一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)
围坐在一张圆桌周围。从编号为k的人开始报数,
数到m的那个人出列;他的下一个人又从1开始报
数,数到m的那个人又出列;依此规律重复下去,
直到圆桌周围的人全部出列。*/
//理解:输入开始的第几个人以及每次数几个人,不停循环喊号,直到剩下最后一个人
/*作业内容:用约瑟夫环写出学号删除系统,每次输入开始的地点以及每次的个数进行删除
剩下的最后一个人进行作业的检查 */
//解法:构建循环链表
#include
#include
typedef struct LinkList
{
int data;
struct LinkList *next;
}LinkList;
/*链表初始化*/
void *star(LinkList **head) //初始化链表,然后方便输入
{
*head=(LinkList*)malloc(sizeof(LinkList)); //初始化分配内存,空间
}
//链表创建
void creat(LinkList *p,int a)
{
LinkList *s; //链表创建
int i=a-1;
p->next=p; //学号赋值
p->data=a;
while(i>0)
{
s=(LinkList*)malloc(sizeof(LinkList));
s->next=p->next;
s->data=i; //循环链表创建并赋值
p->next=s; /*s=(DLinkList*)malloc(sizeof(DLinkList)); //分配新空间
s->next=head->next; //头查法建表
head->next=s;
s->data=x; */
i--;
}
}
//显示内容函数
//便于写程序过程中进行运行以便观察结构正确性
void show(LinkList *p,int a)
{
LinkList *s;
int i=1;
s=p->next;
while(i!=55)
{
printf("%d\n",s->data);
s=s->next;
i++;
}
}
//筛选人员,选取函数
void change(LinkList *p,int m,int n,int a)
{
int num;
int i=1;
LinkList *s,*q,*w; //s为指向学号指针,q方便删除,w记录将要删除结点地址
s=p;
q=p;
while(s->data!=n) //如若没有找到学号为n的人,则继续循环,直到找到
{
s=s->next;
}
while(q->next!=s) //指针q指向前一位置,便于删除
{
q=q->next;
}
// q->next=s->next;
// w=s;
// s=s->next;
// free(w);
while(a!=1) //找每当找到一个人,则需要删除此人学号,然后继续寻找下一个人,直到剩下一个人,即a=1时
{
if(i==m) //if语句,进行查数,如果到达想要删除的第几个数,则进行链表删除操作
{
q->next=s->next; //所删除节点前一结点连接删除节点下一节点
w=s; //保存删除节点地址
a--; //因为删除数据,则数据总数减一
s=s->next; //指针s指向下一结点,继续查询
free(w); //释放删除节点
i=1; //重置i,重新查数
continue; //直接进行下一循环
}
s=s->next; //如果没到达,则继续下一个结点计数
q=q->next;
i++; //计数器加一
}
printf("%d",s->data); //输出最后剩下的学号
}
int main()
{
LinkList *p;
int n,m,num,a; //n为从第n个人开始,m为每次数m个数,num为选取人的学号,a为班级人数
printf("请输入班级人数:");
scanf("%d",&a);
printf("请输入从第几个人开始:");
scanf("%d",&n);
printf("请输入每次数几个数:");
scanf("%d",&m);
star(&p); //链表初始化
creat(p,a); //链表创建
// show(p,a); //展示循环链表,便于观察是否创建成功
change(p,m,n,a); //选择函数,筛选人员
return 0;
}
//待解决问题: 1.链表头部初始化**head原因
// 2.循环链表创建 改变方式以后发现不好用了
/*尝试办法:
s->next=p->next;
p->next=s;
建立以后没有链接上,特意输出过多数,发现并没有循环输出
*/