约瑟夫环的实现

  • 一.问题描述:

         编号为1,2,3,,,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始任选一个正整数作为报数上限值么,从第一个人开始顺时针自1开始报数,报到m时停止报数,报m的那个人出列,将他的密码作为新的密码m的值,从他的顺时针方向的下一个人开始重新从1报数,数到m的那个人出列,如此下去,直到所有的人全部出列。

  • 二.方案设计:

         这个问题的数据结构比较简单,只需将每个人的信息当成一个节点,结点中存放每个人的编号和密码,由于要反复做删除操作,所以采用单向循环链表比较方便。

  •  三.基本步骤:

         建立n个结点的单向循环链表;从链表的第一个结点起计数寻找第m个结点;输出该结点的id,将该结点的password作为新的m的值,删除该结点;根据m的值不断从链表中删除结点,直到链表为空。     

  • 四.代码实现  

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct node
{
int id;                                        //编号 
int password;                          //密码 
struct node *next; 
}Lnode;
Lnode *creat_LinkList()
{
Lnode *H = (Lnode*)malloc(sizeof(Lnode));
int n,i;
printf("请输入总人数:       ");
scanf("%d",&n);
H->next=NULL;
Lnode *s,*r=H;
int num,mm;
for(i=1;i<=n;i++)
{
 printf("请输入第%d个人的密码:",i);
 scanf("%d",&mm);
 s = (Lnode*)malloc(sizeof(Lnode));
 s->id = i;
 s->password = mm;
 s->next=r->next;
 r->next=s;
 r=s;

 s->next=H->next;
return H;

void Delete(Lnode *H,int ipassword)
{   
   Lnode *Pre=H->next,*Pnow=H->next,*Pdel;
   int i=0,t=1;
   while(Pre->next!=H->next)
   Pre=Pre->next;
   while(t)
   {
    for(i=1;i<ipassword;i++)
    {
Pre=Pnow;
    Pnow=Pnow->next;
    }
    if(Pre==Pnow)  t=0;
    Pdel=Pnow;
    Pre->next=Pnow->next;
    Pnow=Pnow->next;
    ipassword=Pdel->password; 
    printf("退出队列的是:第<%d>个人,密码是:<%d>\n",Pdel->id,Pdel->password); 
    free(Pdel);
   }
}
int  main() 
{
Lnode *H=NULL;
    int initpassword;
    H = creat_LinkList();
    printf("请输入初始密码m:    ");
    scanf("%d",&initpassword); 
    Delete(H,initpassword);
    
}



猜你喜欢

转载自blog.csdn.net/los_ATend/article/details/53089096