循环链表解决约瑟夫环问题

问题描述:假设有N个小孩按照序号1,2,,,N围坐成一圈,从第一个小孩开始报数,每次报到n的人退出,接着从下一个人重新开始从1开始报数,下一次再报到n的人退出,求最后一个留下的人;
小孩的个数N,和报数的n由键盘输入;输出留下人的序号
一个循环链表都写得除出了很多问题,改了半天才出来;

#include <stdio.h>

#include <stdlib.h>//包含malloc()

void main()

{

         int N,n;

         int count = 0;

         struct c_list

         {

                   int num;

                   struct c_list *next;

         };

         struct c_list *head,*p1,*p2;//定义了指针,还没有分配空间

         printf("请输入约瑟夫环的大小N\n");

         scanf("%d",&N);

         printf("请输入每次的报号数n:\n");

         scanf("%d",&n);

 

         //循环链表的生成1

         /*

    for(int i = 1; i <= N; i++)

         {

                   if(i == 1)

                   {

                            head = p1 = (struct c_list *)malloc(sizeof(struct c_list));

                            (*head).num = (*p1).num = i;

                   }

                   else if(i < N)

                   {

                            p2 = (struct c_list *)malloc(sizeof(struct c_list));

                            (*p2).num = i;

                            p1->next = p2;

                            p1 = p2;

                   }

                   else

                   {

                            p2 = (struct c_list *)malloc(sizeof(struct c_list));

                            (*p2).num = i;

                            p1->next = p2;

                            p1 = p2;

                            p1->next = head;

                   }

         }

         */

 

         //循环链表的生成2

         head = p1 = (struct c_list *)malloc(sizeof(struct c_list));

         (*head).num = (*p1).num = 1;

         for(int i = 2; i <= N; i++)

         {//p2用来开辟结点,p1只想最后一个结点,对所指的内容赋值前必须先对指针分配内存!!!

                   p2 = (struct c_list *)malloc(sizeof(struct c_list));

                   (*p2).num = i;

                   p1->next = p2;

                   p1 =  p1->next;         

         }

         p1->next = head;//将带链表首尾连起来生成循环链表

 

         //对链表的遍历,删除节点的过程

         if(n == 1) printf("最后剩下的一个人的序号是:\n%d\n",(*p1).num);

         else

         {

         while(count < N-1)

         {

                   for(int j=1;j <= n-2;j++)

                   {

                            head = head->next;

                   }

                   head->next = head->next->next;

                   head = head->next;

                   /*

                   head->next->next = head->next->next->next;

                   head = head->next->next;最初写的报3的代码*/

                   count++;

         }

         printf("最后剩下的一个人的序号是:\n%d\n",(*head).num);

         }

}

posted @ 2011-03-15 12:40  jinmengzhe  阅读(801)  评论(0编辑  收藏  举报