удаление элемента в конкретном связанном списке

Моя программа должна выполнять 3 операции:

  1. Вставлять
  2. Удалить
  3. Показать в круговом связном списке.

Моя проблема в функции удаления. вот код:

void c_list::del()
{
    int num;
    if(isempty())
        cout<<"List is Empty!"<<endl;
    else
    {
        node *temp1=first;
        node *temp2=NULL;
        cout<<"Enter the number that u want to DELETE:"<<endl;
        cin>>num;
        while(temp1->next!=first && temp1->info != num)
        {
            temp2=temp1;
            temp1=temp1->next;
        }
        if(num != temp1->info )
            cout<<"your number was not found in the list"<<endl;
        else
        {
            if(temp2!=NULL)
            {
                temp2->next=temp1->next;
                cout<<temp1->info<<" was deleted"<<endl;        
            }
            else
            {
                first=temp1->next;
                cout<<temp1->info<<"was deleted"<<endl;
            }
        }
    }
    system("pause");
}

Функция удаления работает следующим образом: пользователь вводит число, программа ищет это число и, найдя номер, удаляет его из списка.

Теперь проблема в том, что, когда пользователь вводит номер, которого нет в списке, появляется «Окно сбоя приложения» (я имею в виду это окно: программа не отвечает), в то время как я предоставил сообщение об ошибке для этого случая. («Ваш номер не найден в списке») !!

Вы можете сказать мне, в чем проблема?


person Little Girl    schedule 13.12.2013    source источник
comment
Вы имеете в виду, что программа не отвечает?   -  person benjymous    schedule 13.12.2013
comment
да, это окно появляется   -  person Little Girl    schedule 13.12.2013
comment
Почему у вас одинаковое условие для цикла while и оператора if (temp1->info != num)? Если это ложь, вы даже не будете выполнять инструкции if.   -  person Mahesh    schedule 13.12.2013
comment
Вы уверены, что ваша структура данных верна и в конечном итоге снова достигнете first?   -  person Christopher Creutzig    schedule 13.12.2013
comment
@Mahesh так что я должен писать, если ??   -  person Little Girl    schedule 13.12.2013
comment
@ChristopherCreutzig Я так думаю! Я могу поставить функцию insert (), если хочешь   -  person Little Girl    schedule 13.12.2013
comment
@LittleGirl Циклический связанный список никогда не должен давать сбоев при правильном заполнении. Если удаление не сработало, возможно, это просто логическая ошибка. Пожалуйста, опубликуйте функцию вставки.   -  person Mahesh    schedule 13.12.2013
comment
Вы можете вставить что-то вроде std::cerr << temp1 << std::endl; в свой цикл while и проверить, не заметили ли вы там цикл, который не включает first. (Думаю, использование небольших наборов данных для отладки очевидно.)   -  person Christopher Creutzig    schedule 13.12.2013
comment
В первый пост добавил функцию вставки :)   -  person Little Girl    schedule 13.12.2013
comment
Я предлагаю подумать о том, что происходит, когда первый элемент в списке совпадает с вашим номером. Если это правда, что это круговой список, то этот случай явно неверен. Если это не круговой список, то ваше условие выхода в то время неверно.   -  person Speed8ump    schedule 13.12.2013
comment
ах. Ваш код вставки не создает круговой список.   -  person Speed8ump    schedule 13.12.2013
comment
@ Speed8ump почему ???? Думаю, это правильно! проверьте это одним или двумя примерами: |   -  person Little Girl    schedule 13.12.2013
comment
подумайте, что происходит при первой записи. первый == NULL. что в следующем указателе нового элемента установлено?   -  person Speed8ump    schedule 13.12.2013
comment
когда я ввожу элемент и в первый раз, я создаю узел, следующая часть которого указывает на первый элемент, затем я проверяю, есть ли элемент в списке или нет, если его нет, элемент, который я ввел, будет первая и следующая части будут указывать на себя! О, я должен обновить следующее?   -  person Little Girl    schedule 13.12.2013


Ответы (3)


Ваша процедура вставки не создает круговой список. Когда список пуст и первым вставляется начальный элемент == NULL. В этом случае ваш код покидает список в некруглом состоянии. Так как:

    newitem->next=first;
    if(first==NULL)
        first=newitem;

На этом этапе first-> next == NULL, чего никогда не должно быть в круговом списке. Код поиска не работает, если искомого элемента нет в списке. Это потому, что он никогда не возвращается к первому узлу, поскольку список не является циклическим.

person Speed8ump    schedule 13.12.2013
comment
да ты прав! если я удалю newitem- ›next = first; перед if & измените if на это: if (first == NULL) {first = newitem; newitem- ›next = first;} это будет правильно? - person Little Girl; 13.12.2013
comment
Это, вероятно, исправляет вставку. У вашей процедуры удаления есть другие проблемы. Попробуйте удалить первый элемент из списка и посмотрите, что произойдет. Как только вы это исправите, попробуйте удалить последний элемент из списка. Кроме того, я позволю себе понять, что вы никогда не вызываете delete () для удаляемых элементов. - person Speed8ump; 13.12.2013
comment
ну, еще один вопрос: теперь, когда я изменил вставку, моя функция отображения работает некорректно ... что мне писать в цикле while функции display ()? Я написал while (temp- ›next! = First), но не показывает последний член списка - person Little Girl; 13.12.2013

Я думаю, что в вашем цикле while вы доходите до конца списка, а после строки ниже temp1 получает NULL.

temp1 = temp1-> следующий;

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

если (число! = temp1-> info)

Я знаю, что вы сказали, что это круговой список, но я не уверен, что он реализован правильно или нет. Мое предложение - просто попробуйте напечатать temp1-> info после цикла while, чтобы убедиться, что список и ваша реализация верны.

person Validus Oculus    schedule 13.12.2013
comment
Я добавил код вставки, взглянул на него и сказал, правильно он или нет. tnx - person Little Girl; 13.12.2013
comment
я не вижу вашу функцию вставки, где она? - person Validus Oculus; 14.12.2013

Бывает, что если вы вставляете число, которого нет в списке, у вас будет цикл в первом while.

So:

node* temp1 = first;
node* temp2 = 0; 
while(temp1->next!=first && !temp2) {
  if(temp1->info == num) {
     /* save pointer and exit from while */
     temp2 = temp1;
  } else {
    temp1 = temp1->next;
  }
}

Тогда ваш код производит мусор, потому что вы никогда не вызываете удаление.

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

А потом, почему system («пауза»); ? Взгляните здесь.

person Luca Davanzo    schedule 13.12.2013
comment
Это, вероятно, лучший код, но логически эквивалентный afaics. За исключением того места, где следующий код не может работать с вашим изменением, потому что temp1 указывает на неправильный элемент. - person Christopher Creutzig; 13.12.2013