约瑟夫环是一个数学的应用问题:已知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