理解 约瑟夫环

总结了个小经验,有时候光靠看是看不出什么端倪来的,还必须得动下笔,比划比划也许就那么简单


#include <stdio.h>

#include <stdlib.h>

typedef struct Node

{

 int data;

 struct Node *next;

}Node;

 

Node *CreatList(int n)    //创建一个含n个人的循环链表

{

int i;

Node *head,*p,*q;

head=(Node*)malloc(sizeof(Node));

    head->data=1;

p=head;

for(i=2;i<=n;i++)    //利用尾插法构建长度为n的链表

{

q=(Node*)malloc(sizeof(Node));

p->next=q;

q->data=i;

p=p->next;

}

p->next=head;       //构建循环链表

return(head);

}

 

 

void Joseph(Node *head,int n,int m)  //n:总人数     m:出列的数字

{

int i,j;

Node *p,*q;

    p=head;

for (j=1;j<=n;j++)                                                                                                                      

   {

        for(i=1;i<m;i++)

p=p->next;        //找到应出列的人

          printf("% d",p->data);

          p->data=p->next->data;

          q=p->next;

          p->next=p->next->next;

          free(q);   //释放指针q所指变量的存储空间

   }

}

void main()

{

int n,m;

Node *head;

printf("请输入总人数n:   ");

scanf("%d",&n);

printf("\n请输入出列者报的数m:  ");

scanf("%d",&m);

printf("\n");

head=CreatList(n);    //调用创建列表函数

Joseph(head,n,m);   //调用约瑟夫环函数

printf("\n");

printf("\n");

 

}

自己优化的代码

#include<stdio.h>

#include<stdlib.h>

typedef struct node

{

int data;

node *next;

};

int m,n;

node *head;

void creat()

{

int i;

node *p,*q;

head=(node*)malloc(sizeof(node));

head->data=1;

p=head;

for(i=2;i<=n;i++)

{

q=(node*)malloc(sizeof(node));

p->next=q;

q->data=i;

p=p->next;

}

p->next=head;

}

void jose()

{

int i,j;

node *p,*q;

p=head;

for(j=1;j<=n;j++)

{

for(i=1;i<m;i++)

 p=p->next;           //??????°?p->next??????p???? 

 printf("%d ",p->data);

 p->data=p->next->data;

 q=p->next;      //????q=p;

 p->next=p->next->next;

 free(q);

}

}

int main()

{

while(scanf("%d%d",&n,&m)!=EOF)

{

    creat();

jose();

printf("\n");

}

}

转载于:https://www.cnblogs.com/tanjianwen/p/5245445.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值