/************************************************************************/
/* author: lynnbest 2013.8.24
约瑟夫问题:
有n个人,编号为1,2,3...n围成一个圆圈,按照顺时针方向从编号为k的人
开始报数,报数为m的人出列,她的下一个人重新开始从1报数,数到m的人出列
如此重复下去,知道所有人都出列,编写一个算法,要求输入n,k,m按照出列的
顺序输出编号
exp:
1,2,3,4,5,6,7一圈 n=8,k=2,m=3
则按照输出的编号为:4 7 2 6 3 1 5 8
*/
/************************************************************************/
/************************************************************************/
/* 思路:
1.先创建一个循环链表
2.查找到k元素位置
3.查找到m元素位置
查找到后,先记录下一个节点位置copynode=startnode->next
然后删除节点
跳转到2
4.打印最后一个节点 free()
*/
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}listnode;
void josephus(listnode *h,int n,int k,int m);
void printflist(listnode *h);
listnode *CreateCircleList(int n);
void main()
{
printf(" 约瑟夫问题 \n");
printf("----by lynnbest ----\n\n");
int n,k,m;
printf("输入n,k,m\n");
scanf("%d,%d,%d",&n,&k,&m);
listnode *h=CreateCircleList(n);//创建一个循环列表
printflist(h);
printf("依次退出的编号为:\n");
josephus(h,n,k,m);
}
void josephus(listnode *h,int n,int k,int m)
{
listnode *startnode,*copynode,*pre;
startnode=h;
int i;
//查找到k位置
while(k-1)
{
startnode=startnode->next;
k--;
}
//查找m位置
while(startnode->next!=startnode)//当该节点不是最后一个节点
{
for(i=1;i<m;i++)
{
pre=startnode;
startnode=startnode->next; //startnode为要删除的节点 pre为其前驱节点
}
copynode=startnode->next; //备份当前要删除位置节点的下一个节点
printf("%3d",startnode->data);
pre->next=startnode->next;//删除节点
free(startnode);
startnode=copynode;
}
printf("%4d\n",startnode->data);
free(startnode);
}
void printflist(listnode *h)
{
printf("当前链表元素为:\n");
listnode *p=h;
while(p->next!=h)
{
printf("%4d",p->data);
p=p->next; //漏了
}
printf("%4d\n",p->data);
}
listnode *CreateCircleList(int n)
{
listnode *head=NULL,*newnode,*pre;
for(int i=1;i<=n;i++)
{
if(NULL==(newnode=(listnode *)malloc(sizeof(listnode))))
{
printf("malloc新节点失败\n");
exit(-1);
}
newnode->data=i;
if(NULL==head) //不带头节点的怎么创建 技巧
head=newnode;
else
pre->next=newnode;
pre=newnode;
}
newnode->next=head;//构成循环链表
return head;
}
实战数据结构(4)_循环单链表解决约瑟夫问题
最新推荐文章于 2023-09-20 22:19:27 发布
本文介绍了一个经典的约瑟夫问题解决方案,通过使用循环链表来模拟问题中的报数过程。详细展示了如何创建循环链表,并利用链表特性实现人员出列的算法流程。

543

被折叠的 条评论
为什么被折叠?



