Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удаления значения в списку. Бага 
:(
    Опции темы
sswt
Дата 28.10.2015, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



У меня проблема:  когда я вывожу  значения printBackward  послу удаления головы или следущего значения у меня бага сплывает, printForward нормально выводит  подскажите  где ошибка. Тоесть когда я с хвоста начинаю читать  бага появляеться
Код
void RemoveFirst(DoublyLinkedList* list)
{
    DoublyLinkedList::Node* temp = list->head;
    list->head = temp->nextNode;
    list->head->prevNode = nullptr;
    free(temp);

}

void RemoveAfter(DoublyLinkedList::Node* node)
{
    DoublyLinkedList::Node* temp = node->nextNode;
    node->nextNode = temp->nextNode;
    free(temp);
}
void PrintForward(const DoublyLinkedList* list)
{
    for (DoublyLinkedList::Node* node = list->head; node != nullptr; node = node->nextNode)
        printf("%d\n", node->value);
    printf("\n");
}
void PrintBackward(const DoublyLinkedList* list)
{
    for (DoublyLinkedList::Node* node = list->tail; node != nullptr; node = node->prevNode)
        printf("%d\n", node->value);
    printf("\n");
}
int main()
{
RemoveFirst(list);
    PrintForward(list);
    PrintBackward(list);

    RemoveAfter(list->head);
    PrintForward(list);
    PrintBackward(list);
return 0;
}


PM MAIL   Вверх
math64
Дата 28.10.2015, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



При удалении элементов RemoveFirst и RemoveAfter не проверяешь, пустой ли список.
Нужно также проверить, удаляется ли последний элемент и поправить list->tail если нужно.
PM   Вверх
sswt
Дата 28.10.2015, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



math64
Код
 все равно не пашет
void RemoveFirst(DoublyLinkedList* list)
{
    if (list->head == nullptr) 
    {
        break;
    }
    DoublyLinkedList::Node* temp = list->head;
    list->head = temp->nextNode;
    list->head->prevNode = nullptr;
    if (temp == list->tail) {
        list->tail = nullptr;
    }
    free(temp);
};
}


Это сообщение отредактировал(а) sswt - 28.10.2015, 13:11
PM MAIL   Вверх
feodorv
Дата 28.10.2015, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(sswt @  28.10.2015,  12:38 Найти цитируемый пост)
printForward нормально выводит

Так намёк же - посмотреть, где не правится значение prevNode. Ну, вот здесь правится:
Цитата(sswt @  28.10.2015,  12:38 Найти цитируемый пост)
void RemoveFirst(DoublyLinkedList* list)
{
    DoublyLinkedList::Node* temp = list->head;
    list->head = temp->nextNode;
    list->head->prevNode = nullptr;
    free(temp);
}

А здесь вообще никак:
Цитата(sswt @  28.10.2015,  12:38 Найти цитируемый пост)
void RemoveAfter(DoublyLinkedList::Node* node)
{
    DoublyLinkedList::Node* temp = node->nextNode;
    node->nextNode = temp->nextNode;
    free(temp);
}
Где изменение значения node->nextNode->prevNode? Про, то что node->nextNode может быть nullptr, я даже не намекаю.

Это сообщение отредактировал(а) feodorv - 28.10.2015, 13:30


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
sswt
Дата 28.10.2015, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



feodorv, можете написать как нужно для RemoveFirst, а то я запуталась немножко(((
PM MAIL   Вверх
math64
Дата 28.10.2015, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Не break, а return.
Прежде, чем делать list->head->prevNode = nullptr; нужно проверить  list->head != nullptr;
Аналогичные изменения в RemoveAfter.
Возможны ошибки в невыложенной части кода.

Добавлено через 7 минут и 7 секунд
Цитата(sswt @  28.10.2015,  13:25 Найти цитируемый пост)
можете написать как нужно для RemoveFirst, а то я запуталась немножко((( 

Код

void RemoveFirst(DoublyLinkedList* list)
{
    if (list == nullptr) // списка нет
        return;
    DoublyLinkedList::Node* temp = list->head;
    if (temp == nullptr) // список пуст
        return;
    list->head = temp->nextNode;
    if (list->head != nullptr) // в списке ещё что-то осталось
        list->head->prevNode = nullptr;
    else // список стал пустым
        list->tail = nullptr;
    free(temp);
}

PM   Вверх
sswt
Дата 28.10.2015, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



math64,  не помогло(
PM MAIL   Вверх
feodorv
Дата 28.10.2015, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(sswt @  28.10.2015,  13:25 Найти цитируемый пост)
feodorv, можете написать как нужно для RemoveFirst, а то я запуталась немножко((( 

Думаю, как-то так:
Код

void RemoveAfter(DoublyLinkedList::Node* node)
{
    if( node == nullptr || node->nextNode == nullptr ) return;
    DoublyLinkedList::Node* temp = node->nextNode;
    node->nextNode = temp->nextNode;
    if( node->nextNode != nullptr )
      node->nextNode->prevNode = node;
    else 
      tail = node;
    free(temp);
}



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
sswt
Дата 28.10.2015, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



feodorv, спасибо

Добавлено через 2 минуты и 24 секунды
feodorv,  у нас тут list нету, 
откуда вы берету переменую tail = node; ????
PM MAIL   Вверх
feodorv
Дата 28.10.2015, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(sswt @  28.10.2015,  13:36 Найти цитируемый пост)
feodorv,  у нас тут list нету, 
откуда вы берету переменую tail = node; ???? 

Ааааа. А я было подумал, что:
Код

void DoublyLinkedList::RemoveAfter(DoublyLinkedList::Node* node)
{
  ...
}

А так-то да, лист в аргументы добавить придётся. А если у Вас там ещё head и tail приватные, то придётся браться за голову)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
math64
Дата 28.10.2015, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Либо 1) RemoveAfter(DoublyLinkedList::Node* node) будет методом класса DoublyLinkedList,
либо 2) в DoublyLinkedList::Node нужно добавить поле DoublyLinkedList* list,
либо 3) нужно добавить параметр в RemoveAfter(DoublyLinkedList* list, DoublyLinkedList::Node* node);
Лучше сделать 1) и 2) одновременно и добавить проверку, что node принадлежит нужному списку.

PM   Вверх
sswt
Дата 28.10.2015, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



math64
Код

oid RemoveFirst(DoublyLinkedList* list)
{
    DoublyLinkedList::Node* firstNode = list->head;
    DoublyLinkedList::Node* secondNode = firstNode->nextNode;
    if (secondNode != nullptr)
        secondNode->prevNode = nullptr;
    else
        list->tail = nullptr;
    list->head = secondNode;
    free(firstNode);
}

void RemoveAfter(DoublyLinkedList* list, DoublyLinkedList::Node* node)
{
    DoublyLinkedList::Node* firstNode = node->nextNode;
    DoublyLinkedList::Node* secondNode = firstNode->nextNode;
    node->nextNode = firstNode->nextNode;
    if (node->nextNode != nullptr)
        node->nextNode->prevNode = node;
    else
        list->tail = node;
    free(firstNode);
}

PM MAIL   Вверх
math64
Дата 28.10.2015, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



В обоих случаях нужна проверка firstNode != nullptr.
В RemoveAfter ты заводишь secondNode, но нигде его не используешь (можно сделать как в RemoveFirst).
list != nullptr можешь проверять, а можешь нет - если это гарантировано при вызове.

Добавлено через 4 минуты и 51 секунду
Кстати можно сделать
Код

void RemoveFirst(DoublyLinkedList* list)
{
    RemoveAfter(list, nullptr);
}

и проверять в RemoveAfter на node == nullptr - в этом случае удалять первый элемент списка, код получается похожим.
К сожалению, в RemoveAfter нет контроля, что node принадлежит нужному списку.
PM   Вверх
sswt
Дата 28.10.2015, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 22.9.2015

Репутация: нет
Всего: нет



math64, так ?  та нет лутче поддельности 2 функции  делать
Код

void RemoveAfter(DoublyLinkedList* list, DoublyLinkedList::Node* node)
{
    DoublyLinkedList::Node* firstNode = node->nextNode;
    DoublyLinkedList::Node* secondNode = firstNode->nextNode;
    
    if (firstNode != nullptr)
        secondNode->prevNode = node;
    else
        list->tail = node;
    free(firstNode);
}

PM MAIL   Вверх
feodorv
Дата 28.10.2015, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(sswt @  28.10.2015,  16:45 Найти цитируемый пост)
    DoublyLinkedList::Node* secondNode = firstNode->nextNode;
    
    if (firstNode != nullptr)

Выглядит ужасно. Сначала Вы разименовываете указатель, а затем проверяете, не нулевой ли он. Нужно наоборот.

Добавлено через 7 минут и 33 секунды
Вообще, вся логика по проверке на нулевые указатели нарушена полностью (заодно и логика алгоритма). secondNode тоже может быть нулевым указателем, тогда делать secondNode->prevNode никак нельзя. Если уж Вам так не нравится конструкция node->nextNode->prevNode, то реализовывайте её последовательно:
Код

void RemoveAfter(DoublyLinkedList* list, DoublyLinkedList::Node* node)
{
    DoublyLinkedList::Node* firstNode = node->nextNode;

    if( firstNode != nullptr )
    {
        DoublyLinkedList::Node* secondNode = firstNode->nextNode;
    
        if (secondNode != nullptr) //// not firstNode!!!!
            secondNode->prevNode = node;
        else
            list->tail = node;

        free(firstNode);
    }
}



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1030 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.