12约瑟夫环

/*
    2012
    一群人(排列序号从1到N,N可设定)围成一圈,
按一定规则出列,剩余的人仍然围成一圈.出列规则
是顺着1到N的方向对圈内的人从1到C计数(C可设定),
圈内计数为C的人出列,剩余的人重新计数,按上述规
则,让圈内所有的人出列.请编程顺序输出出列编号的
序列
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node * listNode;
struct node
{
    int data;
    struct node *next;
};

listNode createCircleList(listNode head,int n)
{
    //需要临时生成的临时结点指针,指向循环链表最后一个结点的指针
    int i=1;
    //s是临时结点,p是记录指针,始终指向最后一个结点,head的是传入的头结点指针,头结点不存数据,但是有头结点的更容易后面的操作
    listNode s=NULL;
    listNode p=head;
    while(i<=n){//用的是尾插法
        s=(listNode)malloc(sizeof(struct node));
        s->data=i;
        i++;
        p->next=s;
        p=p->next;
    }
    p->next=head->next;//这句是建立循环的关键,不要漏了
    free(head);//建好循环列表之后,释放掉没有数据的头结点
    return p;//返回的循环链表的最后一个结点,因为这样数数的时候,1就可以代表第一个结点;在主函数中有用
}
int main()
{
    int n,m;
    listNode p=NULL;
    listNode temp=NULL;
    listNode head=NULL;
    head=(listNode)malloc(sizeof(struct node));
    printf("请输入要总个数和要分割的位数,用空格分开:\n");
    scanf("%d%d",&n,&m);
    if(n<m){
        printf("不符合输入条件\n");
        return 0;
    }
    p=createCircleList(head,n);
    int i;
    while(p!=p->next){//循环链表结束的条件是自己指向自己,这样就剩一个结点
        for(i=1;i<m;i++){//找到要删除的结点的前一个结点位置,所以没有等号
            p=p->next;
        }
        temp=p->next;
        printf("%d->",temp->data);
        p->next=temp->next;
        free(temp);
    }
    printf("%d",p->data);//打印出剩下的最后一个结点
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值