n 人圍成一圈,從第 m 人開始報數,每數到 s 就將該人移出圈外,下一人繼續從 1 開始報數,直至所有人移出。輸出移出順序。
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef Node* LinkList;
void CreateJosephLoop(LinkList* L, int number) {
*L = malloc(sizeof(Node));
(*L)->data = 1;
(*L)->next = *L; /* 自環,形成單節點環 */
LinkList tail = *L;
for (int i = 1; i < number; i++) {
LinkList new = malloc(sizeof(Node));
new->data = i + 1;
new->next = tail->next; /* 插入尾部,維持環狀 */
tail->next = new;
tail = new;
}
}
void JosephProblem(int loopSize, int from, int stepBy) {
LinkList L;
CreateJosephLoop(&L, loopSize);
/* 移動到起始位置 */
int seekStart = 1;
while (seekStart < from) {
L = L->next;
seekStart++;
}
/* 開始淘汰 */
while (L->data != L->next->data) { /* 還有超過 1 人 */
for (int i = 1; i < stepBy - 1; i++) /* 走 stepBy-1 步 */
L = L->next;
LinkList temp = L->next; /* 要刪除的節點 */
printf("%d-->", temp->data);
L->next = L->next->next; /* 從環中摘除 */
L = L->next; /* 下一輪從下一人開始 */
free(temp);
}
printf("%d\n", L->data); /* 最後一人 */
}
int main() {
JosephProblem(10, 3, 4); /* 10 人,從 3 開始,報 4 出局 */
JosephProblem(41, 1, 3); /* 經典 41 人、報 3 */
return 0;
}

| 指標 | 數值 |
|---|---|
| 時間複雜度 | O(n × s) —— 每次淘汰需走 s 步 |
| 空間複雜度 | O(n) —— 存儲 n 個節點 |
鏈表解法雖非最優,但直觀展示了「環狀結構 + 指標操作」的核心思想,是資料結構教學與面試經典必考題。