Josephus(约瑟夫环问题)循环单链表c语句实现!

这是在《数据结构与算法分析(c描述)》书中的第三章的3.10练习题,是约瑟夫环的问题,


具体描述:有N个人围成一个圆环,每隔M个人后,第M个被淘汰出局,接着从被淘汰出局者的第二个人开始重新计数计算再次计算M个!

    程序结束条件是当环中只剩下一个人的时候程序就可已结束,并且输出被淘汰的人的编号,以及胜利者的编号。

   

解决这个问题的关键是:1、对链表的基本操作需比较熟悉!

    2、搭建一个循环的单链表!

   3、每次删除一个节点的时候需要跳到他的下一个节点!

                                                          4、注意一些特殊的位置!比如最后一个节点。

 5、当程序还剩下两个人的时候会出现一些bug,本次程序解决了这些bug。



      程序代码如下,只为给新人解解迷惑,高手请多多指点!

#include <stdio.h>

#include <stdlib.h>

/*
** 2015年05月10日 12:28:45
**
**
**
**
**
**
** 关键是在删除到后面只有两个元素的时候那么就会出现错,会多走一步!
*/

#define Test              0

//struct of Josephus
typedef struct Josephus
{
int number;
struct Josephus *next;
}jp;

typedef jp * Jptr;

void
creat_link( Jptr *head , int n )
{
int i = 1;
Jptr p,tail;
tail->next = NULL;
(*head) = tail;

while( i <= n )
{
p = ( Jptr )malloc( sizeof( jp ) );
if( !p )
{
printf(“Sorry,没有可用的内存供您使用程序将退出!”);
exit(0);
}
printf(“请输入第%d个人的编号\n”,i);
scanf(“%d”,&p->number);

tail->next = p;
p->next = NULL;
tail = p;

i++;

}
tail->next = *head;
}

void
output_link( Jptr *head )
{
if( *head == NULL )
{
printf(“The head pointer is NULL !\n”);
exit(0);
}
Jptr p = *head;
while( p->next != *head )
{
p = p->next;
printf(“%d “,p->number);
}
putchar(‘\n’);
}

void
Run( Jptr * head ,int m,int n )
{
int count = 0;
Jptr p = (*head)->next;
Jptr pre = *head;
while( n > 1 )
{
if( count == m )
{
printf(“%d被淘汰\n”,p->number);
pre->next = p->next;
free(p);
p = pre->next;
n–;
count = 0;
continue;
}
count++;
p = p->next;
pre = pre->next;
if( p == *head )
{
p = p->next;
pre = *head;

}
//在程序执行到只剩下两个人的时候会出现一个bug下面这条语句是为了防止这个bug让程序偷了一步!
if( n == 2 && pre == *head )
count++;

}
printf(“%d是赢家!\n”,(*head)->next->number);
}

int
main(void)
{
Jptr head;
int m,n;
printf(“请输入传递次数m以及参与人数n\n”);
scanf(“%d%d”,&m,&n);
creat_link(&head,n);

Run(&head,m,n);
//test
#if Test
output_link(&head);
#endif
return 0;
}

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/Darkness_hades/article/details/45622261
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞