3、循环链表的应用(环路问题)输入一个字符串,以换行结束输入。每个字符存入链表的结点,形成循环链表。从第一个结点开始报数(从1报到5),报到5的出列(下一个结点从1开始报数),直到所有字符出列完毕,输出出列顺序。
时间: 2024-03-10 14:49:50 浏览: 37
好的,这是一个经典的约瑟夫环问题。我来给您讲解一下如何用循环链表来解决。
首先,我们需要用链表来存储输入的字符串。可以定义一个结构体来表示链表的结点,包含一个char类型的数据域和一个指向下一个结点的指针域。
```c
typedef struct node{
char data;
struct node* next;
}Node;
```
接着,我们需要将输入的字符串转化为循环链表。可以使用一个while循环来不断读入输入的字符,并将其插入到链表的尾部。在插入时需要注意特判链表为空的情况。
```c
Node* head = NULL; //链表头指针
Node* tail = NULL; //链表尾指针
char ch;
while ((ch = getchar()) != '\n') {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = ch;
newNode->next = NULL;
if (head == NULL) {
head = tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
tail->next = head; //将链表首尾相连,形成循环链表
```
现在,我们可以开始用循环链表来解决约瑟夫环问题。定义一个计数器cnt,从1开始不断累加。每当cnt的值等于5时,就找到当前结点的前一个结点,将其指向下一个结点,然后将当前结点从链表中删除。
```c
int cnt = 1;
Node* cur = head;
Node* prev = tail;
while (head != NULL) {
if (cnt == 5) {
printf("%c ", cur->data);
prev->next = cur->next;
if (cur == head) {
head = head->next;
}
free(cur);
cur = prev->next;
cnt = 1;
} else {
prev = cur;
cur = cur->next;
cnt++;
}
}
```
最后,我们输出删除结点的顺序即可。
完整代码如下:
阅读全文