【数据结构(一)】(链表习题)约瑟夫环问题
(一).约瑟夫环问题:

方法一:
解:
#include <stdio.h>
#include <malloc.h>
struct node
{
int data; //存猴子编号
struct node* next; //指向node或者另外一个节点
};
int main()
{
int n, m; //n猴子的个数,m报数数到m退出
int i;
int answer[100]; //answer保存每次的答案,最后统一输出
int count = 0; //count用来控制题目答案的下标
struct node* head, * tail, * p, * q;//类似节点,p指向当前,q指向之后
//创建头节点,方便debug跟踪,数据域设置为-1
head = (struct node*)malloc(sizeof(struct node));
//创建一个和struct node大小相同的节点,让这个结构体指针赋值给head
head->data = -1;
head->next = NULL;
while (1)
{
printf("请输入猴子个数n和报数m: \n ");
scanf_s("%d %d", &n, &m); //输入
if (n == 0 || m == 0)
{
free(head);
break;
}
else
{
tail = head;
for (i = 0; i < n; i++)
{
//采用尾插法,tail指向最后一个有数节点
p = (struct node*)malloc(sizeof(struct node));
p->data = i + 1; //填写猴子编号
tail->next = p; //插到尾部
p->next = head->next; //最后节点的next要指向开头,形成环
tail = p; //tail 移动到最后一个节点,为下一次插入作准备
}
p = head->next;
q = tail; //由于环没有最后节点,所以tail和head没什么区别
i = 1;
while (p!=q) //p,q总是一前一后两个节点,如果相遇,证明只剩一只猴子了
{
if (i == m) //i位数,m报数值,相等则删,不等继续查找
{
q->next = q->next->next;
free(p); //将这个节点删除,然后在给p指针重新赋值
p = q->next;
i = 1; //i回归最初,准备进行下一次删除
}
else
{
q = p; //先移后,再移前
p = q->next;
i++;
}
}
head->next = q; //防止链表断开,最好后面加一句这个
answer[count] = p->data; //将最后省的节点记录
free(p); //记录完成后释放节点
count++;
head->next = NULL; //链表已空,要加结尾
}
} //想要退出,则要输0;
printf("\n打印每一次猴王序号为: \n");
for (i = 0; i < count; i++)
{
printf("%d ", answer[i]);
}
return 0;
}
方法二:利用数组实现约瑟夫环
//***********************方法二************************//
#include <stdio.h>
int main()
{
printf("请输入猴子个数n和报数m: \n ");
int n, m;
int i;
int count=1; //代表当前报数
scanf_s("%d %d", &n, &m);
int number = n;
int monkey[300] = { 0 }; //初始化monkey数组
for (i = 0; i < n; i++);
{
monkey[i] = i + 1;
}
int pos = 0; //控制当前数组处理的下标
while (number > 1) //判断猴王
{
if (monkey[pos] > 0)
{
if (count != m) //向后移动 count, monkey[],和pos三者各控制一个数,本质上无关
{
count++;
pos = (pos + 1) % n; //当前处理下标加一
}
else
{
monkey[pos] = 0;
number--;
count = 1; //表示删除一个猴子后重新开始报数
pos = (pos + 1) % n; //当前处理下标加一
}
}
else
{
pos =(pos+1) % n; //当前处理下标加一,跳过monkey[]==0的数
}
}
printf("猴王序号为: \n");
for (i = 0; i < n; i++)
{
if (monkey[i] != 0)
{
printf("%d", monkey[i]);
}
}
return 0;
}
本文探讨数据结构中的经典问题——约瑟夫环,通过链表和数组两种方法详细解析其解决方案,深入理解链表与算法的应用。
】(链表习题)约瑟夫环问题(多种解法)&spm=1001.2101.3001.5002&articleId=114800752&d=1&t=3&u=1fb9810c8cf541f5bb599513971d293c)
6210

被折叠的 条评论
为什么被折叠?



