Проблема со связанным списком - цикл повторяется по неправильным узлам
Если вы не знакомы с проблемой Иосифа:
В круге стоят N солдат. Все они исполняются, начиная с 1 и двигаясь по М. В конце только один из них остается живым. приведенный ниже код запрашивает N и M и генерирует последнего стоящего игрока.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N, M;
struct node { int player_id; struct node *next; }
struct node *p, *q;
int i, count;
printf("Enter N (number of players): "); scanf("%d", &N);
printf("Enter M (every M-th payer gets eliminated): "); scanf("%d", &M);
// Create circular linked list containing all the players:
p = q = malloc(sizeof(struct node));
p->player_id = 1;
for (i = 2; i <= N; ++i) {
p->next = malloc(sizeof(struct node));
p = p->next;
p->player_id = i;
}
p->next = q;// Close the circular linkedlist by having the last node point to the 1st
// Eliminate every M-th player as long as more than one player remains:
for (count = N; count > 1; --count) {
for (i = 0; i < M - 1; ++i)
p = p->next;
p->next = p->next->next; // Remove the eiminated player from the circular linkedl
}
printf("Last player left standing is %d\n.", p->player_id);
return 0;
}
Допустим, N=17;M=7, на выходе должно быть 13, программа, сгенерированная выше, генерирует 2 (что происходит? Хорошо, отсчет начинается с M, а не с 1, поэтому вместо 1,8,15...... он устраняет 7,14......) Здесь я нуждаюсь в вашей помощи (так как связанные списки для меня все еще сложная концепция). Как изменить это?
1 ответ
Вы разместили линию удаления узла в неправильном месте.
for (count = N; count > 1; --count) {
for (i = 0; i < M - 1; ++i)
p = p->next;
p->next = p->next->next;
}
Вы поместили эту строку после цикла, который отсчитывает M узлов с начала, поэтому она всегда начинается с удаления (M+1) -го узла. Вы должны переместить его раньше, чтобы он начинался с первого узла.
for (count = N; count > 1; --count) {
p->next = p->next->next;
for (i = 0; i < M - 1; ++i) p = p->next;
}
Это то, что вы ищете?