在C语言中,使用链表(特别是循环链表)来处理循环报数并移除3的倍数的问题是一个有效的方法。下面我提供一个基本的示例代码,说明如何实现这个功能。
首先,我们需要定义一个链表节点结构体和相关的操作函数。然后,我们可以创建一个循环链表来模拟报数过程,并在每次报到3的倍数时删除该节点,直到链表中只剩下一个节点。
以下是示例代码:
```c
#include
#include
// 定义链表节点
typedef struct Node {
int number; // 节点编号
struct Node *next; // 指向下一个节点的指针
} Node;
// 创建一个新节点
Node* createNode(int number) {
Node *newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
exit(EXIT_FAILURE);
}
newNode->number = number;
newNode->next = NULL;
return newNode;
}
// 在链表末尾添加节点,并使其变为循环链表
void addNodeToCircularList(Node **head, int number) {
Node *newNode = createNode(number);
if (*head == NULL) {
*head = newNode;
newNode->next = newNode; // 循环链表的开始和结束指向同一个节点
} else {
Node *current = *head;
while (current->next != *head) { // 找到链表的最后一个节点
current = current->next;
}
current->next = newNode; // 添加到链表末尾
newNode->next = *head; // 使其成为循环链表
}
}
// 删除链表中报数为3的倍数的节点
void removeMultiplesOfThree(Node **head) {
if (*head == NULL || (*head)->next == *head) { // 空链表或只有一个节点的链表
return;
}
Node *prev = NULL;
Node *current = *head;
do {
if (current->number % 3 == 0) { // 如果报数为3的倍数
if (prev == NULL) { // 如果是头节点
// 寻找新的头节点(跳过当前节点)
do {
prev = current;
current = current->next;
} while (current->next != *head && current->number % 3 == 0);
*head = current; // 更新头节点
if (prev) {
prev->next = current; // 修复前一个节点的指针
}
Node *toDelete = prev ? prev->next : *head; // 要删除的节点
free(toDelete); // 释放内存
if (prev) {
prev->next = current->next; // 跳过被删除的节点
}
} else {
prev->next = current->next; // 直接跳过当前节点
Node *toDelete = current;
free(toDelete); // 释放内存
current = prev->next; // 移动到下一个节点
}
} else {
prev = current;
current = current->next;
}
} while (current != *head && current != prev); // 直到遍历完整个循环链表
// 如果链表中只剩下一个节点,且报数不是3的倍数,则退出循环
if (current == *head && current != prev) {
return;
}
// 如果链表中只有头节点且报数为3的倍数,则删除头节点
if (current == *head && current == prev && current->number % 3 == 0) {
*head = NULL; // 设置为空链表
free(current); // 释放内存
}
}
// 打印链表(仅用于调试)
void printList(Node *head) {
if (head == NULL) {
printf("Empty list\n");
return;
}
Node *current = head;
do {
printf("%d ", current->number);
current = current->next;
} while (current != head);
printf("\n");
}
int main() {
Node *head = NULL;
// 假设我们有10个人,从1开始编号
for (int i = 1; i <= 10; i++) {
addNodeToCircularList(&head, i);
}
printf("Original list: ");
printList(head);
removeMultiplesOf