加里森的任务(循环链表)
其实就是“猴子选大王”的另一个版本,先粘贴上代码
# include<stdio.h>
# include<stdlib.h>
typedef struct Node
{
int data;
struct Node * nextPtr;
}NODE;
typedef NODE * NODEPTR;
NODE * createNode(int n);
void DelList(NODEPTR prev);
NODEPTR Garrison(NODEPTR headPtr,int x,int y);
int main()
{
int n = 0, i = 0, j = 0;
NODEPTR headPtr=NULL;
scanf("%d",&n);
for(i = 1;i<=n;i++)
{
for(j = 1;j<=n;j++)
{
headPtr=createNode(n);
headPtr=Garrison(headPtr,i,j);
if(headPtr->data==1)//输出在士兵数为n时满足要求的x,y
{
printf("When there are %d soldiers , it starts from %d and 'y' is %d.\n",n,i,j);
}
free(headPtr);
}
}
return 0;
}
NODE * createNode(int n)
{
NODEPTR headptr = NULL, curptr = NULL,preptr = NULL;
int num = 1;
while (num<=n)
{ //对n个成员进行创建链表并编号
curptr = (NODEPTR)malloc(sizeof(NODE));
curptr->data = num;
if(preptr != NULL)
{
preptr->nextPtr = curptr;
}
preptr = curptr;
if(headptr == NULL)
{
headptr = curptr;
}
num++;
}
curptr->nextPtr = headptr;//进行首尾链接
return headptr;
}
NODEPTR Garrison(NODEPTR headPtr,int x,int y){
NODEPTR prev = NULL;
int i = 0;
while (headPtr->nextPtr->data != x)//进行遍历,直到指针的下一个节点的编号为x
{
headPtr = headPtr->nextPtr;
}
while (headPtr != headPtr->nextPtr)
{//循环直到只剩下一个节点
for (i = 1; i <= y; i++)
{
prev = headPtr;
headPtr = headPtr->nextPtr;
}
DelList(prev);
headPtr = prev;
}
headPtr->nextPtr = NULL;//将无限循环单节点链表断开
return headPtr;
}
void DelList(NODEPTR prev)//在一位士兵被点到后删除该节点
{
NODEPTR curptr = prev->nextPtr;
prev->nextPtr = curptr->nextPtr;
free(curptr);
}
不过多解释,其中有详细的注释