问题描述
编号为1、2、…按顺时针坐在一张圆桌周围,每人持有一个密码,一个人选任意正整数为报数上限m,从第一个人开始报数报到m时停止报数,这个人出列,直到所有的人都出列,游戏结束。用线性表的内容来实现这个程序。
解决问题的步骤:
第一步:建立n个节点的无头循环链表。
第二步:从链表的第一个节点开始计数,直到寻找到第m个节点第三步:输出该节点的id值,并将其password值,作为新的m值。
第三步:输出该节点的id值,并将其passward值作为新的m的值。
第四步:根据新的m值,不断从链表中删除节点,直到循环链表为空,程序结束。
程序代码
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct NodeType
{
int id;
int password;
struct NodeType *next;
}NodeType;
void CreatList(NodeType **, int);
NodeType *GetNode(int, int);
void PrintList(NodeType *);
int IsEmptyList(NodeType *);
void JosephusOperate(NodeType **, int);
int main(void)
{
int n = 0;
int m = 0;
NodeType *pHead = NULL;
do
{
if (n>MAX)
{
printf("人数太多,请重新输入!\n");
}
printf("请输入人数n(最多%d个):", MAX);
scanf("%d", &n);
} while (n>MAX);
printf("请输入初始密码m:");
scanf("%d", &m);
CreatList(&pHead, n);
printf("\n----------打印循环链表---------\n");
PrintList(pHead);
printf("\n----------打印出队情况---------\n");
JosephusOperate(&pHead, m);
return 1;
}
void CreatList(NodeType **ppHead, int n)
{
int i = 0;
int iPassword = 0;
NodeType *pNew = NULL;
NodeType *pCur = NULL;
for (i = 1; i <= n; i++)
{
printf("输入第%d个人的密码:",i);
scanf("%d", &iPassword);
pNew = GetNode(i, iPassword);
if (*ppHead == NULL)
{
*ppHead = pCur = pNew;
pCur->next = *ppHead;
}
else
{
pNew->next = pCur->next;
pCur->next = pNew;
pCur = pNew;
}
}
printf("完成单向循环链表的创建!\n");
}
NodeType *GetNode(int iId, int iPassword)
{
NodeType *pNew = NULL;
pNew = (NodeType *)malloc(sizeof(NodeType));
if (!pNew)
{
printf("Error, the memory is not enough!\n");
exit(-1);
}
pNew->id = iId;
pNew->password = iPassword;
pNew->next = NULL;
return pNew;
}
void PrintList(NodeType *pHead)
{
NodeType *pCur = pHead;
if (!IsEmptyList(pHead))
{
printf("--ID-- --PASSWORD--\n");
do
{
printf("%3d %7d\n", pCur->id, pCur->password);
pCur = pCur->next;
} while (pCur!=pHead);
}
}
int IsEmptyList(NodeType *pHead)
{
if (!pHead)
{
printf("The list is empty!\n");
return 1;
}
return 0;
}
void JosephusOperate(NodeType **ppHead, int iPassword)
{
int iCounter = 0;
int iFlag = 1;
NodeType *pCur = NULL;
NodeType *pPrv = NULL;
NodeType *pDel = NULL;
pPrv = pCur = *ppHead;
while (pPrv->next != *ppHead)
{
pPrv = pPrv->next;
}
while (iFlag)
{
for (iCounter = 1; iCounter < iPassword; iCounter++)
{
pPrv = pCur;
pCur = pCur->next;
}
if (pPrv==pCur)
{
iFlag = 0;
}
pDel = pCur;
pPrv->next = pCur->next;
pCur = pCur->next;
iPassword = pDel->password;
printf("第%d个人出列(密码:%d)\n", pDel->id, pDel->password);
free(pDel);
}
*ppHead = NULL;
getchar();
}