求解约瑟夫环

有一个问题是这样:0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第3个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3.

思路:首先建立一个循环链表,在对链表不断进行遍历的时候用一个flag变量作为标志位,当遍历第遍历到第二个数时就删除下一个数,也就是第三个数,再将flag置为0,直到链表中只剩一个节点时,取它的数据域即可。

话不多说,上代码:

typedef int data_t;
typedef struct yuesefu       //先定义结构体a
{
    data_t data;
    struct yuesefu *next;
}*circle;
int main(int argc, char *argv[])
{ 
    int n,a,len=0,flag=1;            //变量依次代表 输入的数字个数,输入的数字,链表长度,标志位
    circle head,p,r;                 //p,r作为辅助指针 
    head=(circle)malloc(sizeof(data_t));    //创建头节点 
    p=head;
    scanf("%d",&n);                        
    while(n--)                               //循环用于给新节点数据域赋值      
    {
        scanf("%d",&a);
        circle q=(circle)malloc(sizeof(data_t));    
        q->data=a;
        p->next=q;
        p=q;
        len++;
    }
    p->next=head->next;      //将尾节点连接到首节点(首节点不是头节点,一般是头节点的下一个节点)         
    p=head->next;
    r=p;                    
    free(head);              //释放头节点,使链表成为一个循环链表
    while(len!=1)
    {
        if(flag==2)             
        {
            r=p->next;            //当计数到2时,将指针r指向p的下一个节点,也就是计数为3的节点
            printf("%d ",r->data);       
            p->next=r->next;            //将p指向r的下一个节点,也就是删除r节点
            free(r);                    //释放r所指空间内存
            flag=0;                     //标志位清零
            len--;                      //链表长度减1
        }                                
         p=p->next;                    //继续从新的节点开始计数
        flag++;
    }
    putchar('\n');           
    printf("最后剩余的元素为:%d\n",p->data);     
    
    
    return 0;
} 

需要注意的一点是在对标志位赋初值和重置标志位的时候对应的数值,我们通常开始计数时从1开始,所以标志位初值应赋值为1,而在重置标志位时可以理解为将需要删除的节点标记为0,那么从下一个新节点开始就是从1开始计数
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值