C语言--使用单链表解决25个人围成一个圈,从第一个人开始顺序报号,凡报号为3或3的倍数者退出圈子,找出最后留下来的人的初始序号

本人为C语言初学者,在自学的途中遇到了这样一个问题。

25个人围成一个圈,从第一个人开始顺序报数,凡报号为3或3的倍数者退出圈子,找出最后留下来的人的初始序号。

因为是在我学习完结构体和单链表之后遇到的测验,我就开始用这俩个方法进行解题。以下代码为我的解题步骤,仅为记载学习过程,也非常希望各位大佬指点。

代码效果为:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)
//25个人围成一个圈,从第一个人开始顺序报号,凡报号为3或3的倍数者退出圈子,找出最后留下来的人的初始序号
typedef struct student {
    int or_id;//初始序号
    int id;//序号
    struct student* next;
}student;
//新增链表方法,用于初始化链表
student* add(student* head, int n) {
    for (int i = 1; i < n+1; i++)
    {
        student* p = (student*)malloc(sizeof(student));
        student* last = head;
        p->or_id = i;
        p->next = NULL;
        if (last)
        {
            while (last->next)
            {
                last = last->next;
            }
            last->next = p;
        }
        else
        {
            head = p;
        }
    }
    return head;
}
//打印链表方法
void pr(student* head) {
    for ( head; head; head=head->next)
    {
        printf("初始ID为%d,ID为%d\n", head->or_id,head->id);
    }
    
}
//删除链表方法,用于删除序号为3的链表,返回head值
student* del(student* head,int *n) {
    //p为当前链表,p1为前一个链表
    student* p, * p1;
    p1 = head;
    for ( p=head; p; p1=p,p=p->next, (*n)++)
    {
        //判断链表是否为空
        if (head)
        {
            p->id = *n;
            //需要删除的链表在中间
            if (p->id%3==0&&p->next!=NULL&&p!=head)
            {
                p1->next = p->next;
            }
            //需要删除的链表在最后
            else if(p->id % 3 == 0 && p->next == NULL)
            {
                p1->next = NULL;
            }
            //需要删除的链表在最前
            else if (p->id%3==0&&p==head) {
                head = p->next;
            }
        }
    }
    return head;
}
int main() {
    student* head = NULL;
    //k为记载序号值
    int k = 1;
    //i记载这是第几次调用删除方法
    int i = 0;
    int* k1 = &k;
    head = add(head, 25);
    while (head->next)
    {
        head = del(head,k1);
        i++;
        printf("**************************第%d次删除后的效果*********************\n",i);
        pr(head);
    }
    
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值