您的位置:首页 > 其它

约瑟夫问题

2014-11-21 00:00 621 查看
摘要: 用单向循环链表实现“数3出局”游戏(Josephu问题)。首先建立一个包含若干整数的单向循环链表,然后从第一个节点开始数,把数到3的那个节点删除,接着下一个节点开始数,数到3继续删除,以此类推,打印出最后剩余的那个节点。

/*
**************约瑟夫问题*************
** 		  josephu.c				**
**		平台:Ubuntu12.04           **
** 	时间: 2014-11-20			**
*************************************
*/

//   用单向循环链表实现“数3出局”游戏(Josephu问题)。首先建立一个包含若干整数的单向循环链表,然后从第一个节点开始数,把数到3的那个节点删除,接着下一个节点开始数,数到3继续删除,以此类推,打印出最后剩余的那个节点。
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
typedef int   datatype; //定义为泛型,以后更改数据类型  只需将int换成其他,如double
typedef struct node{
datatype  data;
struct node *next;
}link_node,*plink_node;

void Init_linklist(plink_node *pH);
void Creat_josephu(plink_node H,int n);
void Show_josephu(plink_node H);
void Josephu(plink_node H);

int main(void)
{

int num;		   	// 游戏人数
plink_node H;		 // 定义头结点

Init_linklist(&H);  //初始化头结点

printf("please input num! \n");
scanf("%d",&num);//输入游戏人数

Creat_josephu(H,num);  //创建游戏人数

Show_josephu(H); //显示

Josephu(H);//Josephu算法

return 0;
}
void Init_linklist(plink_node *pH)
{
*pH = (plink_node)malloc(sizeof(link_node));
if(NULL==(*pH))//
{
perror("Head malloc failed:");
exit(1);
}
(*pH)->next = *pH;//头尾结点相连  注意:*pH要加括号,* 优先级比 -> 低

}
void Creat_josephu(plink_node H,int n)
{
int i;
plink_node q;
plink_node tail = H;
for(i=1;i<=n;i++)
{
if(1==i) //  想想  1==i  比i==1 有何不同? 优点在哪?
H->data = i;//头结点赋值
else
{
q = (plink_node)malloc(sizeof(link_node));

//插入结点
q->next = tail->next;
tail->next = q;

q->data = i;

tail = tail->next;//移动链表尾
}
}

}
/*******************************************************/
void Show_josephu(plink_node H)
{
plink_node p = H;
while(p->next != H)//判断是否为头结点
{
printf("%d ",p->data);
p = p->next; //往后移动
}
printf("%d\n",p->data);//
}

void Josephu(plink_node H)
{
int i = 1;
plink_node p,q;
plink_node t;

/* 假设游戏人数编号:1     2  		 3    4      5   6           */
/*		 p  p->next		 q  q->next  		         */
p = H;//记住头结点  就是记住1号
while(p->next != p)
{
q = p->next->next;//这就是要删除的结点q ,q就是3号
printf("第%d轮:  %d出局  \n",i++,q->data);

p->next->next = q->next; //   q->next是4号,4?号接到p->next->next (原3号位置),
p = q->next;//第二次数的开始结点,也就是4号开始数起
free(q);
q = NULL;

/*  打印剩余成员*/
t =	p;
printf("剩余成员:");
while(t->next != p)
{
printf("%d ",t->data);
t = t->next;
}

printf("%d \n\n",t->data);
//	Show_josephu()
}
printf("胜利者:%d \n",p->data);
}

(ps:第一次写,如有不妥之处,请指正)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息