不带有头结点的循环单链表解决约瑟夫环问题
时间: 2023-06-05 21:48:04 浏览: 183
约瑟夫环问题可以使用不带有头结点的循环单链表来解决。具体方法是先创建一个循环单链表,然后将所有人依次加入到链表中。接着,从链表的头部开始,每隔m个人就将这个人删除,直到链表中只剩下一个人为止。最后剩下的那个人就是幸存者。
需要注意的是,在删除一个人之前,需要先找到这个人的前一个人,以便将其从链表中删除。另外,由于是循环单链表,所以在计算每隔m个人时,需要将当前位置加上m-1,以便找到要删除的人的位置。
相关问题
Java采用循环单链表求解约瑟夫环问题的代码实现
以下是Java实现约瑟夫环问题的代码,采用循环单链表:
```
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
public class JosephusCircle {
public static int findLastRemainingNum(int n, int m) {
Node head = new Node(0);
Node prev = head;
for (int i = 1; i < n; i++) {
Node curr = new Node(i);
prev.next = curr;
prev = curr;
}
prev.next = head;
Node curr = head;
while (curr.next != curr) {
for (int i = 1; i < m - 1; i++) {
curr = curr.next;
}
curr.next = curr.next.next;
curr = curr.next;
}
return curr.val;
}
}
```
该算法的时间复杂度为 O(n * m),其中 n 为链表长度,m 为报数的步长。
c语言使用一个带有头结点的循环链表解决约瑟夫环问题
好的,约瑟夫环问题可以使用循环链表来解决。下面是使用带有头结点的循环链表来实现的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义结点
typedef struct node {
int data;
struct node *next;
} Node;
// 创建循环链表
Node *createList(int n) {
Node *head = (Node*)malloc(sizeof(Node));
head->data = 0;
head->next = NULL;
Node *tail = head;
for (int i = 1; i <= n; i++) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = i;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
tail->next = head->next; // 将链表尾部指向头结点
return head;
}
// 删除结点
void deleteNode(Node *p) {
p->next = p->next->next;
}
// 约瑟夫环
void josephus(Node *head, int m) {
Node *p = head;
while (p->next != p) {
// 找到第m个结点
for (int i = 1; i < m; i++) {
p = p->next;
}
deleteNode(p);
}
printf("%d\n", p->data);
}
int main() {
int n, m;
scanf("%d%d", &n, &m); // 输入总人数和每次数m
Node *head = createList(n);
josephus(head, m);
return 0;
}
```
在上面的代码中,我们首先定义了一个结点结构体,然后创建了一个带有头结点的循环链表。接着定义了一个删除结点的函数,最后实现了约瑟夫环的功能。在约瑟夫环中,我们每次从头结点开始找到第m个结点,然后删除该结点,直到链表中只剩下一个结点为止。最后输出剩下的那个结点的编号即为答案。
阅读全文