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
",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: 
");
            continue;
            
        }
        else
            break;
        
    }
    
    CreateList(&pHead,n);
    printf("the original circle LinkList to print 
");
    prntList(pHead);
    printf("The status of deleting Nodes to print... 
");
    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! 
");
    
    
}

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 
", 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 
", 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! 
");
        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!
");
        return TRUE;
    }
    return FALSE 
}
原文地址:https://www.cnblogs.com/Shareishappy/p/7523647.html