链表法解决约瑟夫环问题

/**********************************************************
* Copyright (c) 2012年9月1日 , 嵌入式第七组
* All rights reserved.
* 文件名:josephus.c
* 功能描述:用链表实现约瑟夫环问题。
* 作 者:第七组成员
* 版 本:V1.0
* 日 期:2012-09-1
* 其他说明:
* 函数列表:
* 1.CHILD *creat(void):创建循环约瑟夫环链表
* 2.void print(CHILD *head):打印约瑟夫环链表值
*
* 修改记录:
*
**********************************************************/
#include<stdio.h> //包含库头文件
#include<malloc.h>
#include<stdlib.h>

typedef struct jose CHILD;//
#define LEN sizeof(CHILD) //定义LEN的为结构体CHILD的存储空间
struct jose
{
long int num;
struct jose *Next;
}; //定义一个结构体

CHILD *creat(void); //声明创建循环约瑟夫环链表函数
void print(CHILD *head); //声明打印约瑟夫环链表值函数

void main()
{
int n,i=0;
int j=0; //被删除的孩子的个数
CHILD *head,*p1,*p2;
head=p1=p2=creat(); //创建孩子信息
print(p1); //打印孩子各个号码
if(head!=NULL) //约瑟夫环链表不为空
{
printf(“请输入你要选择的数:”);
scanf(“%d”,&n); //出列的数字
while(1)
{
if(head->Next==head) //留下最后一个值
{
head->Next=NULL;
printf(“剩下的孩子号码为:%d”,head->num);//输出结果
break;
}
else
{
i=i+1;
if(i==n-1) //每隔n-1个数据,则删除下一个数据
{
j=j+1;
printf(“第%d个出局孩子的号码为:%d\n”,j,p1->Next->num);
p1->Next=p1->Next->Next;
head=p1->Next;
p1=head;
i=0;
}
else
{
p1=p1->Next; //头指针往后移动
head=p1;
}
}
}
}
}

/**********************************************************
* 函数名:*creat(void)
* 功能描述:创建一个循环约瑟夫环链表
* 输 入:无
* 输 出:指向链表头的指针
**********************************************************/
CHILD *creat(void)
{
CHILD *head,*p1,*p2; //定义指向CHILD的结构体变量
int count=0; //定义创建CHILD的个数count,并初始化为0
p1=p2=(CHILD *) malloc(LEN); //开辟一个CHILD的空间给p1,p2
printf(“请输入第%d个孩子的号码(-1添加结束):”,count+1);
scanf(“%d”,&p1->num); //添加孩子号码
getchar();
head=NULL; //初始head指向NULL
while(1)
{
count++; //每增加一个成员,count加一
if(p1->num==-1) //孩子号码为-1是链表创建结束标记
{
free(p1);
break;
}
else if(1==count) //如果为第一个孩子,则head指向p1
{
head=p1;
}
else
{
p2->Next=p1;
}
p2=p1;
p1=(CHILD *) malloc(LEN); //开辟一个CHILD的空间给p1
printf(“请输入第%d个孩子的号码(-1添加结束):”,count+1);
scanf(“%d”,&p1->num);
}
p2->Next=head; //链表成员输入完成,形成环链表
return head;
}

/**********************************************************
* 函数名:print(CHILD *head)
* 功能描述:打印约瑟夫环链表值
* 输 入:CHILD *head:约瑟夫环链表的头指针
* 输 出:无
**********************************************************/
void print(CHILD *head)
{
CHILD *p;
p=head;
if(head!=NULL)
{
printf(“\n孩子号码依次为:\n”);
do
{
printf(“%d\n”,p->num);
p=p->Next;
}while(p->Next!=head->Next);
}
else
{
printf(“没有输入号码!”);
}
}

总结

     在编写程序时,必须了解解决该问题的各个细节,尤其是一些特色情况。同时还要考虑各行代码的顺序问题,我在写本程序时,就把creat子程序中删除结点中的p1->Next=p1->Next->Next;printf(“第%d个出局孩子的号码为:%d\n”,j,p1->Next->num);没有正确排序,导致结果错误,检查好久才发现。程序难免会遇到问题,在遇到问题时,我们还要有足够的耐心和细心检查错误。这样才能成为一个好的程序员。

    原文作者:约瑟夫环问题
    原文地址: https://www.cnblogs.com/djky/archive/2012/09/03/2669418.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞