利用线性表解决约瑟夫生死游戏
一、实验内容:
n个人排成一个环形,依次顺序编号1,2,…,n。从第1号开始,沿环计数,每数到第m个人就让其出列,且从下一个人开始重新计数,继续进行下去。这个过程一直进行到剩下k个旅客为止。
二、实验分析:
其数学模型归结如下:
数学模型:假设n个人排成一个环形,依次顺序编号1,2,…,n。从第1号开始,沿环计数,每数到第m个人就让其出列,且从下一个人开始重新计数,继续进行下去。这个过程一直进行到剩下k个旅客为止。
三、代码实现:
1.源程序:
#include <stdio.h>
#include <malloc.h>
typedef struct Node {
int Num;
struct Node *next;
}Node, *PNode, *HeadNode;
int ListInit(HeadNode *h)
{
if (!h)
{
printf("初始化链表错误!\n");
return 0;
}
(*h)->next = (*h);//循环单链表
return 1;
}
int ListInsert(Node *h, int pos, int x)/*尾插法*/
{
PNode p = h, q;
int i = 1;
if (pos == 1)
{
p->Num = x;
p->next = p;
return 1;
}
while (i<pos - 1)
{
p = p->next;
i++;
}
q = (PNode)malloc(sizeof(Node));
q->Num = x;
q->next = p->next;
p->next = q;
return 1;
}
void ListTraverse(HeadNode h, int M)
{
int i = 0;
PNode p = h;
printf("参与的人的编号为:\n");
while (i<M)
{
printf("%d\t", p->Num);
p = p->next;
i++;
}
printf("\n");
}
//囚犯处死函数
int ListDelete(HeadNode h, int M, int k)
{ int i;
PNode p = h, q;
while (M>1)
{
for (i = 1; i<k - 1; i++)
{
p = p->next;
}
q = p->next;
p->next = q->next;
printf("被处决囚犯的序号为%d\n", q->Num);
free(q);
p = p->next;
M--;
}
printf("被赦免的囚犯为:%d", p->Num);
return 1;
}
int main() {
int i;//计数器
int n;//囚犯的人数
int m;//每轮要处决的序号
printf("请输入囚犯总人数:");
scanf_s("%d", &n);
printf("请输入要处决的囚犯序号:");
scanf_s("%d", &m);
HeadNode h = ((HeadNode)malloc(sizeof(Node)));
ListInit(&h);
for (i = 1; i <= n; i++)
{
ListInsert(h, i, i);
}
ListTraverse(h, n);
if (m > 1)
ListDelete(h, n, m);
else
{
for (i = 1; i < n; i++)
printf("出局的人为:%d号\n", i);
printf("被处决的囚犯的编号为:%d", n);
}
printf("\n");
printf("\n");
return 0;
}
2.执行结果: