Мой совет:
Не используйте индексы со списками, вы можете сделать то же самое с указателями на узлы. Вам не нужно переходить к индексу, указатели на узлы быстрее.
Вы должны изменить алгоритмы, чтобы использовать указатели на узлы:
Нахождение последнего слова:
Вы перебираете список, если вы находите узел, который является пробелом, вы сохраняете указатель на этот узел в переменной, если вы достигли конца списка, запоминаемый указатель на узел - это пробел перед последним словом , Вам просто нужно изменить следующие узлы. Если вы никогда не нашли узел, содержащий пробел, вы можете просто заменить весь список заменой.
Еще один прием - использовать двойные указатели, в которых хранится указатель на указатель, который указывает на узел последнего слова. (Это также может быть корнем списка)
// node** p is a pointer to the pointer of the first element
// if your root is defined as `node* root`, you use
// `... = last_word(&root);`
node** last_word(node** p) {
node* n = *p;
while(n) {
if(n->data == ' ') p = &n->next;
n = n->next;
};
return p;
};
Вставка узла:
Вы получили указатель из алгоритма, подобного last_word
, который является указателем на указатель на узел. Он указывает на переменную, в которой хранится указатель на следующий узел (об этом есть видео с ComputerPhile), это полностью разделяет вставку в начале, конце и в середине:
void insert(node** p, char c) {
node* elem = (node*)malloc(sizeof(node));
elem->data = c;
elem->next = *p; // connect to following node
*p = elem; // connect previous node/root to the node
};
И если вам действительно нужно работать с индексами , вам следует всегда разбивать код на отдельные функции.
node** node_by_index(node** p, int index) {
while(index > 0) {
p = &(*p)->next;
--index;
};
return p;
};