约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
C代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct _node
{
struct _node* next;
int number;
}node,*linklist;
linklist create(int n);//生成一个不带头结点的单向循环链表
void joseph(linklist head, int k, int m);
int main()
{
linklist head;
int m, n, k;
printf("please input n:");
scanf("%d",&n);
printf("please input m:");
scanf("%d",&m);
printf("please input k:");
scanf("%d",&k);
head = create(n);printf("the sequences of leaving the list are:");
joseph(head,k,m);
return 0;
}
linklist create(int n)
{
linklist head = (linklist)malloc(sizeof(node));
node *tail;
int i;
head->next = head;//循环链表:保证最后一个结点的next域指向第一个结点
head->number = 1;
tail = head;
for(i=2;i<=n;i++)//以尾插法的方式建立链表
{
node *p = (node*)malloc(sizeof(node));
p->number = i;
p->next = tail->next;
tail->next = p;
tail = p;
}
return head;
}
void joseph(linklist head, int k, int m)
{
int j;
node *p = head;
node *q;
for(j=1; j<k; j++)//得到开始报数的位置k对应的结点
p = p->next;
while(head->next != head)//当循环链表中只剩下一个结点时,结束循环
{
for(j=1; j<m-1; j++)//找到第m个结点的前驱结点
p = p->next;
q = p->next;//待删除的m结点
p->next = q->next;
printf("%d ",q->number);
if(q == head)//如果待删除的m结点是第一个结点,则需要修改head指针
head = q->next;
free(q);
p = p->next;//从删除结点的下一个结点开始计数
}
printf("%d\n",head->number);//输出最后一个结点的值
}
原文:http://blog.csdn.net/hs794502825/article/details/37991467