本人为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);
}
}