數據結構 約瑟夫環 利用單向循環鏈表存儲結構模擬約瑟夫環,按照出列的順序打印出各人的編號和此人對應的密碼。

1、實驗原理node

約瑟夫問題描述:編號爲1,2,……,n的n我的按順時針方向圍坐一圈,每人持有一個密碼(正整數)。一開始任選一個正整數做爲報數的上限值m,從第一我的開始按順時針方向自1開始順序報數直到報m的人,將此人刪除,並將他的密碼做爲新的m值,從他在順時針方向上的下一我的開始從新從一報數,……,如此下去,直到全部人所有出列爲止。               實現:利用單向循環鏈表存儲結構模擬約瑟夫環,按照出列的順序打印出各人的編號和此人對應的密碼。函數

2、參考程序spa

#include  <stdio.h>指針

#include  <stdlib.h>code

/*--------------------------結構體------------*/io

typedef struct Lnode          /*  結點的結構定義  */ 原理

   {  int  num;              /*  編號子域        */List

      int  sm;               /*  密碼子域        */循環

      struct Lnode *next;        /*  指針域          */ 程序

   }Lnode,*LinkList;

/* 函數聲明   */

LinkList creat();

void  print1(LinkList  h);

void  print2(LinkList  h);

LinkList shanchu(LinkList h);

void outs(LinkList  h, int m);

 

/*  主函數  */

 main()

 { int  m;  LinkList  head;

   head=creat();

   print1(head);//帶頭結點輸出(實際上是跳過了頭結點)

   head=shanchu(head);

   print2(head);//刪除頭結點後輸出

   printf("\n  enter the begin secret code, m=m>1");   scanf("%d",&m);

   outs(head, m);//按照密碼輸出

 }  /* main  */


/*  建立約瑟夫環 帶頭結點的單鏈表 */

 LinkList  creat()

{  int  i=0, mi;

   LinkList  h,p2,p1;

   h=( LinkList)malloc(sizeof(Lnode));

   p1=h;

   p1->next =h;

   printf("\n 我的密碼爲: ");  scanf("%d",&mi);

   while( mi != -111)                    //  密碼爲-111,結束循環  

    {

   p2=( LinkList)malloc(sizeof(Lnode));  //  申請數據元素結點空間

       i++;

   p2->num=i;

   p2->sm=mi;

   p2->next=h;//連成環

   p1->next=p2;

   p1=p2;

       printf("\n 我的密碼爲:  ");  scanf("%d",&mi);   // 讀入下一個密碼  

   }  //while  

   return(h);

 }   

/*---------------------------------------帶頭結點輸出(跳過頭結點輸出)----------------*/

 void  print1(LinkList  h)

   {

    LinkList q;

q=h->next;

printf("帶頭結點鏈表輸出:\n");

// 與頭插法建立鏈表對應的輸出函數

while (q!=h)

{   

printf("%6d %6d  \n",q->num,q->sm);

q=q->next;

}

 }

   LinkList shanchu(LinkList h){

    LinkList m,p;

m=h;

for(p=h;p->next!=h;p=p->next);

p->next=h->next;

h=h->next;

free(m);

return(h);

   }

/*----------------------刪除頭結點後輸出-------------------*/

   void  print2(LinkList  h)

   {

    LinkList r;

r=h;

printf("不帶頭結點鏈表輸出:\n");

    while (r->next  !=h )

{  

printf("%6d %6d  \n",r->num,r->sm);

r=r->next;

}

   printf("%6d %6d  \n",r->num,r->sm);// 頭指針指向第一個數據元素結點

  }

/*--------------------------------按照密碼輸出某我的------------*/

  void outs(LinkList  h, int m)

{  int i;   LinkList q=h,p;

  printf("\n ");

  while (q->next!=q)

   { for(i=1;i<m;i++){ p=q; q=q->next;}      // 報數到第m我的

     printf("%6d %6d\n ",q->num,q->sm);     //  輸出第m我的的編號和密碼  

     m=q->sm;

     p->next=q->next;  free(q);           //  m我的出列

     q=p->next;

    }

  printf("%6d %6d  \n",q->num,q->sm);         //   輸出最後一個結點的編號值

  free(q);

} //outs