/**************************************************************         
* Copyright (c) 2013, 西华师范大学计算机学院                 
* All rights reserved.                                       
* 作 者:  曾舜尧                                            
* 完成日期:2013 年 05 月 26 日                              
* 工 具:VC6.0                                               
*                                                            
* 输入描述:                                                 
* 问题描述:通过链表实现,13个人围成一圈,从第一个开始顺序报号1、
*           2、3.凡报到3者推出圈子找出最后留在圈子中的人的序号。                       
* 程序输出:                                                 
* 问题分析:略                                               
* 算法设计:略                                               
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
 struct Man           /*定义结构体*/
{
    int n;            /*计数*/
    int tag;          /*标记*/
    struct Man *next; /*指向下一个*/
};
int main()
{
    struct Man* create(struct Man *head,int n);
    struct Man* select(struct Man *head,int n,int e);
    struct Man  *man=NULL,*p=NULL;
    int pos=3;
    const int n=13;/*共计13个对象*/
      
    man=create(man,n);
    man=select(man,n,pos);
    /*遍历那个特殊数*/
    for (p=man;!(p->tag);p=p->next);/*p->tag==0*/
    printf("通过链表实现,猴子选大王问题。。。。\n");
    printf("那个特殊数是%d \n",p->n);
    system("pause");
    return 0;
}
struct Man* create(struct Man *head,int n)
{
    int i=0;
    struct Man *p=NULL,*q=NULL;
    while (i++<n)/*控制循环,创建13个对象*/
    {
        if (i==1)
        {
            p=malloc(sizeof(struct Man));
            q=p;
            head=p;
        }
        else
        {
            p=malloc(sizeof(struct Man));
            q->next=p;
            q=p;
        }
        p->n=i;
        p->next=NULL;
        p->tag=i;
    }
    p->next=head;
    //printf("循环了%d次\n",p->n);/*检验循环*/
    return head;
}
struct Man* select(struct Man *head,int n,int e)
{
    struct Man *p;
    int i=0;
    int j=0;
    p=head;
    while (i<n-1)  /*i==0*/
    {
        j=0;
        /*第一种方法标记淘汰的*/
        /*while (1)
        {
            if(p->tag)    //p->tag!=0
                j++;
            if(j==e)
                break;
            p=p->next;
        }*/
        /*第二种方法标记淘汰的*/
        for (j=0;j!=e;(p->tag!=0)?j++:1,j!=3?(p=p->next):p);
          
        //printf(" 删除的ID%3d  ",p->n);/*检验循环*/
        p->tag=0;
        i++;
        p=p->next;
    }
    return p;
}