C ++ односвязный список с использованием классов - PullRequest
1 голос
/ 14 марта 2012

Я хочу создать односвязный список (используя классы), где в каждом списке будет: указатель на текст, номер int, указатель на следующий список.

Мне нужно реализовать 3 функции: вставляет (который вставляет список в односвязный список и сортирует элементы с помощью strcmp по тексту, на который указывает указатель) удаляет (int num), который удаляет первый список, в котором встречается номер. print (), которая печатает весь односвязный список.

У меня проблема с функцией удалений, которая выдает ошибку во время выполнения, и у меня есть предположение, где проблема if ( tmp->next == NULL && tmp->number==num ) { delete tmp; first = NULL; }, но я понятия не имею, почему это так.

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

Вот код:

    #include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

class list
{
private:
    int number;

    char* word;
    list* next;
public:
    void inserts(int num, char* text);
    void removes(int num);
    void print();
};
list* first;

void list::print() {
    cout <<"This is our list:"<<endl;

    // Temp pointer
    list *tmp = first;

    // No nodes
    if ( tmp == NULL ) {
    cout << "EMPTY list" << endl;
    return;
    }

    // One node in the list
    if ( tmp->next == NULL ) {
    cout <<"NUMBER:\t"<< tmp->number;
    cout <<"\tWORD:\t"<< tmp->word << endl;
    cout <<"--------------------------------"<<endl;

    }
    else {
    // Parse and print the list
    while ( tmp != NULL ){
         cout <<"NUMBER:\t"<< tmp->number;
         cout <<"\tWORD:\t"<< tmp->word << endl;
         cout <<"--------------------------------"<<endl;

        tmp = tmp->next;
    }
}
}

void list::inserts(int num, char* word){
    // Create a new list
    list* newlist = new list; 
    newlist->number=num;

    newlist->word=word;
    newlist->next=NULL;

    // Create a temp pointer
    list *tmp = first;

    if ( tmp != NULL ) {
    // Nodes already present in the list
    // Parse to end of list
    while ( tmp->next != NULL ) {
        tmp = tmp->next;
    }

    // Point the last node to the new node
    tmp->next=newlist;
    }
    else {
    // First node in the list
    first = newlist;
    }
}

void list::removes(int num){
int k = 0;
    list* tmp=first;
    if(tmp==NULL)
        return;
       //Last node of the list

   if ( tmp->next == NULL && tmp->number==num ) {
    delete tmp;
    first = NULL;
    }
    else {
    //Parse thru the nodes
    list* prev;
    prev = new list;
    while ( tmp != NULL )
    {
        if ( tmp->number == num && k == 0)
            first = first->next;
if ( tmp->number == num)
break;
        prev = tmp;

        tmp = tmp->next;
k++;
    } 

    //Adjust the pointers
    prev->next=(tmp->next);
    //Delete the current node
delete tmp;
delete prev;

}
}


int main ()
{
    first->print();
    first->inserts(1200,"endian");
    first->print();
   /* first->inserts(10,"endianness");
    first->inserts(1200,"PEEK");
    first->inserts(1200,"POKE");
    first->inserts(1200,".MIL");
    first->print();*/
first->removes(100);
first->print();
getchar();
}

Ответы [ 3 ]

1 голос
/ 13 сентября 2012

Избавьтесь от delete prev; в последней строке функции removes().

Я не эксперт, но удаляя prev, вы теряете ссылку на свой первый узел в списке.

Кстати, хорошие комментарии сделали его очень удобным для чтения!

0 голосов
/ 14 марта 2012

Когда этот цикл выполняется:

while ( tmp != NULL )

ваш указатель tmp достигнет конца списка и при разрыве цикла будет иметь значение NULL

Итак, когда вы выполните:

prev->next=(tmp->next);

ваш временный указатель не имеет значения "next". Возможно, вам следует поддерживать другой указатель вне цикла.

0 голосов
/ 14 марта 2012

В removes, после цикла while ( tmp != NULL ) { … }, tmp возможно NULL.

Но после этого цикла у вас есть следующие строки:

//Adjust the pointers
prev->next=(tmp->next);

Вы разыменовываете указатель NULL, который вызывает сбой вашей программы.

Замените эти строки этими:

//Adjust the pointers
if(tmp)
    prev->next=(tmp->next);

<ч /> Также обратите внимание: у вас все еще есть ошибка в управлении памятью в подпрограмме removes. Вы никогда не вызываете delete с начальным значением prev, и вы удаляете узел списка, который вы должны хранить в определенных случаях. Вместо того, что вы делаете, инициализируйте его так: list* prev=0; и избавьтесь от delete prev.

...