Обратный LinkedList С++


person Maroun    schedule 23.10.2012    source источник
comment
Да, это C++, дайте Node несколько методов. Пусть они поменяются местами в списке, не меняя значения. Затем найдите оба конца списка и поменяйте их местами, продвигаясь вперед, пока не достигнете одного и того же узла на обоих концах или тех, которые вы только что поменяли местами.   -  person CashCow    schedule 23.10.2012
comment
Вы никогда не назначаете _head, не так ли?   -  person Xeo    schedule 23.10.2012
comment
Добавьте _head = prev; после цикла while.   -  person Anton Guryanov    schedule 23.10.2012
comment
Я пробовал, это не помогло. Я все еще получаю ››1 в качестве вывода.   -  person Maroun    schedule 23.10.2012
comment
Так и должно быть. Если вы добавите _head = prev после цикла while, ваш код будет полностью идентичен моему ответу здесь. Я также попробовал и проверил его на LWS.   -  person Xeo    schedule 23.10.2012
comment
Спасибо, Xeo, моя функция printList может вызвать проблему... хотя она хорошо печатает перед реверсированием.   -  person Maroun    schedule 23.10.2012
comment
Действительно.. Я вызывал его один раз до и один раз после реверсирования.. (я путешествовал с самим _head.. что вызвало проблему)   -  person Maroun    schedule 23.10.2012


Ответы (3)


Поскольку вы сказали, что хотите найти проблему самостоятельно, я просто дам вам подсказку вместо решения.

Ваша функция reverse работает в том смысле, что она успешно переворачивает список. Это не проблема. Вероятно, у вас есть 2 звонка на print. Один до и один после реверса. Что вы заметили в отношении узлов, передаваемых print в обоих случаях? О чем тебе это говорит?

РЕДАКТИРОВАТЬ:

Поскольку вы сказали, что нашли проблему, я опубликую фактическое решение.

В вашем коде reverse вы никогда не обновляете _head списка, но когда вы reverse списка, заголовок действительно меняется с 4 на 1. Поскольку вы никогда не обновляете _head, когда вы вызываете print во второй раз (после вызова reverse), вы начинаете печатать с 1, это конец списка, это единственный напечатанный узел.

Решение состоит в том, чтобы обновить _head, когда вы переворачиваете список. Самый простой способ сделать это — просто обновлять его на каждой итерации. Это может быть немного менее эффективным, чем другие возможные решения, но это не меняет временную сложность алгоритма - это все еще O (n):

void LinkedList::reverseList()
{
    Node *next=_head;
    Node *prev=0;
    while(next!=0)
    {
        Node *tmp=next->_next;
        next->_next=prev;
        _head = next;
        prev=next;
        next=tmp;
    }
}
person John Dibling    schedule 23.10.2012
comment
Функция printList не получает никаких параметров, она начинается с _head и затем перемещается до конца списка (пока 0 не станет следующим из последнего узла). - person Maroun; 23.10.2012
comment
Теперь понял..спасибо большое :) - person Maroun; 23.10.2012
comment
Пожалуйста. Вы хотите, чтобы я опубликовать решение сейчас? - person John Dibling; 23.10.2012
comment
Конечно .. теперь я это исправил :) Мне нужно было использовать копию _head, а не саму _head для функции печати. - person Maroun; 23.10.2012
comment
@Maroun: Ой, это плохая идея, да. :) Вы бы заметили это, если бы сделали своего print участника const! Как в void print() const{ ... }. - person Xeo; 23.10.2012
comment
Действительно .. 'const' может сэкономить много времени :) спасибо - person Maroun; 23.10.2012

Попробуйте что-нибудь вроде этого.

Двусвязный список:

for (Node * n = _head, * next; ; n = next)
{
    next = n->next;

    std::swap(n->next, n->prev);

    if (next == NULL) { _head = n; break; }
}

Односвязный список:

for (Node * n = _head, * prev = NULL, * next; ; prev = n, n = next)
{
    next = n->next;

    n->next = prev;

    if (next == NULL) { _head = n; break; }
}
person Kerrek SB    schedule 23.10.2012
comment
Моя первая мысль точно, но, похоже, это односвязный список. - person bitmask; 23.10.2012
comment
Там никогда не упоминается n->prev. :) - person Xeo; 23.10.2012
comment
Хорошо, я сделал две версии, одну для двойного и одну для одиночного списка. - person Kerrek SB; 23.10.2012
comment
Я попробую этот .. Может кто-нибудь объяснить, почему мой код не работает? Что мне здесь не хватает? - person Maroun; 23.10.2012
comment
@ Maroun85: Разве Ксео уже не объяснил это? Вы никогда не переназначаете _head в своем коде. - person Kerrek SB; 23.10.2012

мне нравится рекурсия; Это легче понять и проверить;

Node* LinkedList::reverseList() { // returns tail
  if (!_head || !_head->_next)
      return _head;
  Node* const h = _head;
  _head = _head->_next;
  h->_next = NULL;
  return reverseList()->_next = h;
}
person bitmask    schedule 23.10.2012