约瑟夫问题
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:第一次写,如有不妥之处,请指正)