Josephus问题 循环链表
来源:互联网 发布:萤石云软件下载 编辑:程序博客网 时间:2024/05/17 23:12
Josephus问题是下面游戏:N个人从1到N编号,围坐成一个圆圈,从1号开始传递一个热土豆。经过M次传递后拿着热土豆的人被清除离座,围坐人圆圈缩紧,由坐在被清除的人后面拿起热土豆继续进行游戏。最后剩下的人取胜。因此,如果M=0和N=5,那么0到4依次被清除后,5号获胜。同理,M=1和N=5,那么依次被清除的顺序是2,4,1,5
问题有点像之前碰到的:猴子选大王。之前用数组写,后来发现效率不高,需要的是对清除的数组赋值0;
采用循环链表时,只需删除相应的节点,剩余最后一个节点就是该局获胜的人
#include"stdio.h"
#include"stdlib.h"
#define Error(str) fprintf(stderr,"%s\n",str),exit(1)
#define ElementType int
struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
int IsEmpty(List L);
Position Insert(ElementType X,Position P);
Position Find(ElementType X,List L);
void Delete(List L);
List CreateList(void);
void PrintLots(List L,List P);
struct Node
{
ElementType Element;
Position Next;
};
/*
函数:CreateList()
功能:创建一个循环链表,首节点为1;
*/
List CreateList(void)
{
List L;
L=(List)malloc(sizeof(struct Node));
if(L==NULL)
Error("get the position failed!");
L->Next=L;
L->Element=1;
return L;
}
/*
函数:IsEmpty(L)
描述:判断链表时候为空;PS其实本例程中不需要此函数,写的时候习惯了
*/
int IsEmpty(List L)
{
return L->Next==L;
}
/*
函数: Find(X,L)
描述:X为需要查找的关键字,L为查找的链表
功能:查找X在L中所在位置
*/
Position Find(ElementType X,List L)
{
Position P;
P=L->Next;
while(P!=NULL&&P->Element!=X)
{
P=P->Next;
P->Element=1;
}
return P;
}
/*
Insert(X,P)
描述:X,为需要的链表长度,P为首节点
功能:根据传递的X,建立相应长为X的循环链表
*/
Position Insert(ElementType X,Position P)
{
Position Head;
Head=P;
int i=2;
while(i<=X)
{
Position TmpCell;
TmpCell=(List)malloc(sizeof(struct Node));
if(TmpCell==NULL)
Error("Out of space!");
TmpCell->Element=i;
TmpCell->Next=P->Next;
P->Next=TmpCell;
P=TmpCell;
i++;
}
return Head;
}
/*
Delete(L)
功能:删除循环链表;在本例程中,最后只剩一个节点
*/
void DeleteList(List L)
{
List FirstCell;
while(L->Next!=NULL)
{
FirstCell=L->Next;
L->Next=FirstCell->Next;
free(FirstCell);
}
}
/*
Josephus(num,num_member)
描述:num为需要循环的次数,相当于问题中的M,num_member为人数,相当于N
*/
void Josephus(ElementType num,ElementType num_member)
{
List L;
L=CreateList();
L=Insert(num_member,L);
Position HeadL;
Position Tail;
Position Precur;
Position Dele;
int count=num_member;
int i;
HeadL=L;
while(L->Next!=HeadL)//找到循环链表的尾节点
L=L->Next;
Tail=L;
Dele=Tail->Next;
Precur=Tail;
while(1)
{
if(count==1)//使用count作为一个计数器,判断剩余人数
break;
else
{
for(i=0;i<num;i++)
{
Precur=Dele;
Dele=Dele->Next;
}
Precur->Next=Dele->Next;
free(Dele);
Dele=Precur->Next;
--count;
}
}
printf("%d",Precur->Element);
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
Josephus(a,b);
return 0;
}
- Josephus问题 循环链表
- 循环链表--解决Josephus问题
- 循环链表应用------Josephus环问题
- 循环链表解josephus问题
- 循环链表应用-Josephus
- 约瑟夫问题(Josephus Problem) 用双向循环链表实现
- Josephus约瑟夫环问题循环链表实现
- josephus问题->不带头节点的循环链表
- 循环链表解决Josephus环问题
- josephus 约瑟夫的循环链表实现
- 链表应用:Josephus问题
- 约瑟夫(Josephus)问题的求解——利用循环链表
- 双向循环链表解决Josephus(约瑟夫)问题
- 循环链表解决Josephus环轮流报数问题
- <C>Josephus问题——用循环链表解决
- Josephus问题的链表实现
- 链表形式的josephus问题
- 约瑟夫问题(Josephus)链表实现
- 稳定和不稳定排序
- nyoj32(全排列)
- CentOS6.3
- 虹膜识别(一)--基于几何特征确定中心点
- c/c++ 表达式求值
- Josephus问题 循环链表
- Quicksort
- wget命令用法详解
- Hdu 5094 Maze(状压dp+bfs)
- 【原创】皇冠店主教你如何打造淘宝爆款,金钱买不到的经验
- 工厂方法模式
- Sex matters needing attention in the winter
- 一个拓扑排序问题
- hiho一下 第十一周——树中的最长路