最近又重新写了一次约瑟夫环。
一. 约瑟夫环问题概述:
设有n个人围坐在一- 个圆桌周围,现从第s个人开始报数,数到第m个的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,..... 如此反复直到所有的人全部出列为止。对于任意给定的n、s和m,求出按出列次序得到的n个人员的序列。
二. 步骤
1.创建由 n个结点组成的不带头结点的Josephus循环单链表
2.找循环链 表中的第s个结点
3.求第m 个应出列的元素删除它
三. 相关代码
# include<stdio.h>
# include<stdlib.h>
typedef struct Node
{
int data;
struct Node * pNext;
}Node, *pNode; //pNode相当于Node *
pNode creat_list(int n){
pNode pHead, pTail;
pHead = (pNode)malloc(sizeof(Node));
if(pHead == NULL)
{
printf("空间不足,分配失败!\n");
exit(-1);
}
pTail = pHead;
pHead->data = 1;
pHead->pNext = NULL;
for(int i=2; i<=n ;i++){ //尾插法,从第2个节点开始创建并往后边的节点中存入数据
pNode pNew = (pNode)malloc(sizeof(Node));
if(pNew == NULL)
{
printf("空间不足,分配失败!\n");
exit(-1);
}
pNew->data = i;
pNew->pNext = NULL;
pTail->pNext = pNew; //前一个指针指向新插入节点
pTail = pTail->pNext; //末尾指针往后移
}
pTail->pNext = pHead; //开始循环链表,最后一个指针指向第一个位置
return pHead;
}
void traverse(pNode pHead) //遍历链表
{
pNode a = pHead;
while(a->pNext != pHead)
{
printf("%d ", a->data);
a = a->pNext;
}
printf("%d\n", a->data); //此时a已经指向了最后一个节点
}
void getyue(pNode pHead,int s, int m){
pNode a = pHead, b = NULL;
if( s==1 && m==1) //输出一个删一个
{
while(pHead != a->pNext)
{
printf("%d ", a->data);
b = a->pNext;
free(a); //清除当前节点内存,防止内存泄漏
a = b; //此句表明a指针已经往后移
}
printf("%d\n", a->data); //最后一个节点内容
}
else
{
for(int i=1; i<s ; i++) //找到s
{
a = a->pNext;
}
if( m==1)
{
printf("%d ", a->data);
while(pHead->pNext != pHead)
{
b = a->pNext;
a->pNext = b->pNext; //删除当前节点
printf("%d ", b->data);
if(b == pHead)
{
pHead = b->pNext;
}
free(b);
}
}
else
{
while (a != a->pNext) { //当链表中只剩一个节点时结束
for(int i=1;i<m;i++){ //找到m前的那一个节点
b = a;
a = a->pNext;
}
printf("%d ", a->data);
b->pNext = a->pNext; //删除当前节点
free(a);
a = b->pNext;
}
printf("%d\n", a->data);
}
}
}
int main()
{
pNode pHead = NULL;
int n=0, m=0, s=0;
printf("请依次输入小组人数、从第几个人开始报数、报到数字几的人出局(中间用空格隔开):\n");
scanf("%d %d %d", &n, &s, &m);
pHead = creat_list(n);
printf("\n当前人员序列: ");
traverse(pHead); //遍历输出
printf("\n出列人员序列: ");
getyue(pHead, s, m);
printf("\n");
return 0;
}
四. 运行结果
五. 总结
一开始只写了s!=1, m!=1的情况,后边测试多次后发现不得行,根据着测试结果又进行了多次修改调试,最后成了上述代码结果。可能仍有错误或是考虑不周的情况,欢迎大家指出!(还是得多打代码诶~)