002 -- Circle LinkList_Josephus Story
Circle List puzzle
Josephus Story:
there is 41 people , 39 of them have the agreement that: all these 41 people stand as a circle, and one of them count from 1, and the one count to 3, suicide ! and the people next to him count from 1 again, untill all 41 people are dead. But Josephus and his friend don't want to die, so they have their location arranged, and become the last 2 person for counting.
// give a number m, n people as a circle and start say a number with 1, the one with number m to say, get out of the circle
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}node;
node *create(int n)
{
node *p = NULL, *head;
head = (node*)malloc(sizeof(node));
p = head;
node *s;
int i = 1;
if(0!n)
{
while(i<=n)
{
s = (node*)malloc(sizeof(node));
s->data=i++; //initiate the circle list, the first node is 1; the secode node is 2
p->next = s;
p=s;
}
s->next = head->next;
}
free(head);
return s->next;
}
int main()
{
int n = 41; //total 41 people_initiate a list with 41 nodes
int m = 3; //who count to 3, out of circle _delete the node
int i;
node *p = create(n);
node *temp;
m = n%m; //m=2
while(p!=p->next) //if p = p->next, means only 1 node left in the list
{
for (i=1;i<m-1;i++)
{
p=p->next; //now p come to the node before the deleting node, only run 1 time
}
printf("%d", p->next->data); //print the value of the node who going to be deleted
temp = p->next;
p->next = temp->next;
free(temp);
p=p->next; // now p point to the node who will start count with 1
}
printf("%d\n",p->data); //print the last node of the list
return 0;
}
Advanced history
N people with a code (max M) and stand as a circle, with the first people's code such as 6, as the counter , the one counting 6 , out of the circle and his code is 9, and the next round will count with the code 9...untill all the people out.
#include <stdio.h>
#include <stdlib.h>
#define MAX_NODE_NUM 100
#define TRUE 1U
#define FALSE 0U
typedef struct NodeType
{
int id;
int cipher;
struct NodeType *next;
} NodeType;
/*create circle Linklist*/
static void CreateList(NodeType **, const int);
/*run Jehus puzzel*/
static void StatGame(NodeType **,int);
/*print the circle link list*/
static void PrntList(const NodeType *);
/*get a Node*/
static NodeType *GetNode(const int, const int);
/*test if the link list is empty, if it's empty, return True, else, False*/
static unsigned EmptyList(const NodeType *);
int main(void)
{
int n,m;
NodeType *phead = NULL;
while(1)
{
printf("please enter the amount of people(maximize %d): ", MAX_NODE_NUM);
scanf("%d", &n);
printf("and the initiate code: ");
scanf("%d", &m);
if(n>MAX_NODE_NUM)
{
printf("Too many people, please re-enter: \n");
continue;
}
else
break;
}
CreateList(&pHead,n);
printf("the original circle LinkList to print \n");
prntList(pHead);
printf("The status of deleting Nodes to print... \n");
StatGame(&phead,m);
}
static void CreateList(NodeType **ppHead, const int n)
{
int i, iCipher;
NodeType *pNew, *pCur;
for(i=1;i<=n;i++)
{
printf("please input %d people's code: ", i);
scanf("%d",&iCipher);
pNew = GetNode(i,iCipher);
if(*ppHead==NULL)
{
*ppHead = pCur = pNew;
pCur->next = *ppHead;
}
else
{
pNew->next = pCur->next;
pCur->next = pNew;
pCur = pNew;
}
}
printf("Finish the circle LinkList creation! \n");
}
static void StatGame(NodeType **ppHead, int iCipher)
{
int iCounter, iFlag = 1;
NodeType *pPrv, *pCur, *pDel;
pPrv = pCur = *ppHead;
while(pPrv->next != *ppHead)
pPrv = pPrv->next; // set pPrv points to the last node, prepare for deleting
while(iFlag)
{
for(iCounter = 1; iCounter < iCipher; iCounter++)
{
pPrv = pCur;
pCur = pCur->next;
}
if(pPrv == pCur)
iFlag = 0;
pDel = pCur; //delete the node which pCur points to.
pPrv->next = pCur->next;
pCur = pCur->next;
iCipher = pDel->cipher;
printf("The %d man is out, code: %d \n", pDel->id,pDel->cipher);
free(pDel);
}
**ppHead = NULL;
getchar();
}
static void PrntList(const NodeType *pHead)
{
const NodeType *pCur = pHead;
if(EmptyList(pHead))
return;
do
{
printf("The %d man, his code is: %d \n", pCur->id, pCur->cipher);
pCur = pCur->next;
}
while(pCur!pHead);
getchar();
}
static NodeType *GetNode(const int iId, const int iCipher)
{
NodeType *pNew;
pNew = (NodeType *)malloc(sizeof(NodeType));
if(!pNew)
{
printf("Error, the memory is not enough! \n");
exit(-1);
}
pNew->id = iId;
pNew->cipher = iCipher;
pNew->next = NULL;
return pNew;
}
static unsigned EmptyList(const NodeType *pHead)
{
if(!pHead)
{
printf("The list is empty!\n");
return TRUE;
}
return FALSE
}