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

#c #algorithm #data-structures #linked-list #singly-linked-list

Вопрос:

 #include <iostream>
using namespace std;

class Node{
    public:
        int data;
        Node *next;
};
class LinkedList{
    Node *head;
    public:
        //Node *head;
        LinkedList(){
            head=NULL;
        }
        void addAtTail(int);
        void print();
};
void LinkedList::addAtTail(int val){
    Node *nodeToAdd=new Node();
    nodeToAdd->data=val;
    if(head==NULL){
        head=nodeToAdd;
    }
    else{
        Node *temp=head;
        while(temp!=NULL){
            temp=temp->next;
        }
        temp->next=nodeToAdd;
    }
}
void LinkedList::print(){
    Node *temp=head;
    while(temp->next!=NULL){
        cout<<temp->data;
        temp=temp->next;
    }
}
int main()
{
    LinkedList ll;
    ll.addAtTail(10);
    ll.addAtTail(20);
    ll.addAtTail(30);
    ll.print();
    cout<<"Hello World";
    return 0;
}
 

я попытался составить связанный список, разделив его на функции. Он построен успешно, но ничего не печатает, может ли кто-нибудь сказать мне о моей ошибке. Во-первых, в этом посте я попытался удалить узел, которого не было в функциях, теперь у меня есть еще одно сомнение, что я создаю связанный список с использованием функций .

Комментарии:

1. C и C — это разные языки. Если вы на самом деле не компилируете как то и другое или не просите сравнить или отличия в вашей ситуации, вы, как правило, должны включать только применяемый языковой тег.

2. Я тот парень, который просто бросает комментарий, жалуясь на то, что связанные списки в стиле C преподаются на C . Эта реализация хуже, чем та, в которой требуется, чтобы меню было частью реализации связанного списка. Если вам необходимо иметь меню, по крайней мере, при каждом выборе вызывайте соответствующую функцию связанного списка и не соединяйте меню и связанный список вместе.

3. Единственный способ «удалить» узел-это использовать delete ключевое слово. Все, что выделено, new должно иметь соответствующее delete . Ваша идея «удаления» без использования ключевого слова является утечкой памяти и неправильной.

4. это крошечная деталь, но имхо лучше показать код, в котором действительно есть описанная вами проблема, т. Е. //delete curNode->next; -> > delete curNode->next; . Любой отдельный символ, который мы должны изменить в вашем коде, чтобы воспроизвести проблему, является источником путаницы и непонимания

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

Ответ №1:

Для начала ваш код не различает позицию, равную 0, и позицию, равную 1, потому что для обеих позиций это цикл while

                while(i<pos-1){
                curNode=curNode->next;
                i  ;
                }
 

не будет исполнено.

Также в цикле вы не проверяете curNode , становится ли указатель равным нулю.

Это заявление

 curNode->next=curNode->next->next;
 

также может вызывать неопределенное поведение в случае, если curNode->next указатель имеет значение null.

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

Вы можете переписать этот фрагмент кода, например, следующим образом

            else{
               cout<<"Enter Position - ";
               cin>>pos;
               
               if ( pos < 0 )
               {
                   std::cout << "Invalid position.n";
               }
               else
               {
                   Node **curNode = amp;head;
                   
                   while ( *curNode amp;amp; pos-- )
                   {
                       curNode = amp;( *curNode )->next;
                   }

                   if ( *curNode == nullptr )
                   {
                       std::cout << "Invalid position.n";
                   }
                   else
                   {
                       Node *tmp = *curNode;
                       *curNode = ( *curNode )->next;
                       delete tmp;
                   }
               }

               break;
           }
 

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

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

Комментарии:

1. можете ли вы помочь мне с правильными изменениями в коде ?

2. Привет, как вы сказали, я выплюнул свой код в функции, я пробовал, но он ничего не печатает, вы можете мне помочь, пожалуйста?

3. @NamanVerma {обращаю внимание на то, что менять исходный код в вопросе таким кардинальным образом-плохая идея. Это только собьет с толку читателей вопроса и ответов. Вы должны восстановить исходный код. Затем вы должны закрыть текущий вопрос, выбрав лучший ответ, и после этого задать новый вопрос с новым кодом.

Ответ №2:

при вставке узла вы делаете temp=NULL, а затем NULL->next=nodeToAdd, что приведет к ошибке

поэтому сделайте условие while как while(temp->next!=NULL)

В случае печати вы не собираетесь до последнего узла, для этого измените условие while на while(temp!=NULL)

 void LinkedList::addAtTail(int val){
    Node *nodeToAdd=new Node();
    nodeToAdd->data=val;
    if(head==NULL){
        head=nodeToAdd;
    }
    else{
        Node *temp=head;
        while(**temp->next!=NULL**){
            temp=temp->next;
        }
        temp->next=nodeToAdd;
    }
}
void LinkedList::print(){
    Node *temp=head;
    while(**temp!=NULL**){
        cout<<temp->data;
        temp=temp->next;
    }
}