2016-08-05 26 views
-4

Ich habe ein paar Stunden verbringen diese Lösung, aber ich denke, es wäre besser, wenn mir jemand dabei helfen könnte:Warum speichert diese benutzerdefinierte verknüpfte Liste nicht jedes in C++ angegebene Element?

struct node{ 
    int x; 
    node *next; 
}; // basic node struct 

class LinkedList{ 
private: 
    node *head; 
public: 
    LinkedList(int init){ // initalizating the list 
     head = new node; 
     node *rot = new node; 
     rot->next = 0; 
     rot->x = init; 
     head->x = -1; 
     head->next = rot; 
     cout << "added: " << head->next->x << endl; 
    } 

    void add(int adds){ 
     if(head != 0) { 
      while (head->next){ // goes to the latest head 
       head = head->next; 
      } 
     } 
     node *rot = new node; 
     rot->next = 0; 
     rot->x = adds; 
     head->next = rot; 
     cout << "added: " << head->next->x << endl; 
    } 

    int push_last() { // pushes the last element, works fine 
     node *temp = head; 
     while(temp->next) 
      temp = temp->next; 

     return temp->x; 
    } 

    int push_first(){ //shows the penultimate element instead of first one 
     return head->x; 
    } 

}; 

int main() 
{ 
    LinkedList lt(1); 
    lt.add(2); 
    lt.add(3); 
    lt.add(4); 
    cout << lt.push_first() << endl; // prints 3/the penultimate element each time 
    cout << lt.push_last() << endl; // prints last element always(4 in this case) 
    return 0; 
} 

ich das nicht will wie meine Hausaufgaben suchen, weil es wirklich isn t. Ich habe versucht, es für ein paar Stunden herauszufinden, es viel zu ändern, danke für jede Hilfe!

Edit: es neu geschrieben:

class LinkedList{ 
private: 
    node *head; 
public: 
    LinkedList(int init){ head = new node; 
    head->next = nullptr; 
    head->x = init; 
    } 
    void add(int toadd){ 
     node *tnode = head; 
     while(tnode->next!= nullptr){ 
      tnode = tnode->next; 
     } 
     tnode->next = new node; 
     tnode->next->x = toadd; 
     tnode->next->next = nullptr; 
    } 
    void print(){ 
     node *tmp = head; 
     while(tmp->next!=nullptr){ 
      cout << tmp->x << endl; 
      tmp = tmp->next; 
     } 
     cout << tmp->x << endl; 


    } 
}; 

int main() 
{ 
    LinkedList lt(1); 
    lt.add(3); 
    lt.add(62); 
    lt.add(123); 
    lt.add(9521); 
    lt.print(); 
    return 0; 
} 
+2

Was haben Sie beobachtet, wenn durch den Code Schritt den Debugger? –

+2

Soll in der 'add'-Funktion wirklich geändert werden, wo die Member-Variable' head' zeigt? Dadurch verlieren Sie den ursprünglichen Kopf. –

+2

Beachten Sie, dass 'push' normalerweise ** ** etwas zu einem Container hinzufügt, also ist' push_first' ein eigentümlicher Name. –

Antwort

1

In Ihrem Add-Funktion, Sie bewegen den Kopfzeiger auf das letzte Element, alle bisherigen Elemente zu verlieren (und deren Speicher undicht).

sollten Sie eine temporäre verwenden, wie Sie push_last

+0

Habe ein paar Änderungen gemacht und jetzt scheint es zu funktionieren, Post bearbeitet, danke für die Hilfe. – pitar

0
void add(int adds){ 
    if(head != 0) { 
     while (head->next){ // goes to the latest head 
      head = head->next; 
     } 
    } 
    node *rot = new node; 
    rot->next = 0; 
    rot->x = adds; 
    head->next = rot; 
    cout << "added: " << head->next->x << endl; 
} 

in tun Hier ist das Problem

head->next = rot; 

Diese immer an der Vorderseite der Liste, nachdem Kopf den neuen Knoten hinzufügt.

Da Sie angegeben haben, dass dies eine Lernübung ist, ist es eine Überarbeitung Ihres Codes mit einigen Hinweisen. Ich fügte einen Destruktor hinzu, entkoppelt das Hinzufügen von Knoten aus dem Aufbau der Liste, enthielt aber einen create-and-add-ctor, der die Delegierung der beiden Operationen demonstriert (Erstellen der leeren Liste und Hinzufügen des ersten Knotens), ich fügte einen last_node Helfer hinzu eine empty Funktion.

I umbenannt auch push_first und push_last: in Bezug wie diese Behälter, push fast immer eine Bewegung gibt, während Ihre Funktionen Accessoren einfach waren. Ich umbenannte dann front und back, die eine Konvention ist, die von der Standardbibliothek verwendet wird.

Ich zog auch die Node Struktur innerhalb der Klasse LinkedList und machte es privat (Mitgliedschaft in einer class ist private standardmäßig und Node vor dem public Accessor definiert ist). Wenn es von außen sichtbar wäre, würde dies LinkedList::Node machen.

#include <iostream> 

using std::cout; 
using std::endl; 

class LinkedList 
{ 
    struct Node 
    { 
     int x; 
     Node *next; 
    }; 

    Node *head; 

    // get a pointer to the last node in the list. 
    // returns: head if the list is empty. 
    Node* last_node() 
    { 
     Node* cur = head; 
     while (cur->next) 
      cur = cur->next; 
     return cur; 
    } 

public: 
    LinkedList() 
     : head(new Node { -1, nullptr }) 
    { 
    } 

    // If you absolutely have to have a constructor that adds a node: 
    LinkedList(int adds) : LinkedList() 
    { 
     add(adds); 
    } 

    ~LinkedList() // destructor 
    { 
     // Free all of the nodes we created 
     Node *next; 
     for (Node* cur = head; cur != nullptr; cur = next) { 
      next = cur->next; 
      delete cur; 
     } 
    } 

    void add(int adds) 
    { 
     Node* tail = last_node(); 
     tail->next = new Node { adds, nullptr }; 
     cout << "added: " << tail->next->x << endl; 
    } 

    bool empty() const 
    { 
     return (head->next == nullptr); 
    } 

    // returns: value of the last node (-1 if list is empty) 
    int back() 
    { 
     return last_node()->x; 
    } 


    // Normal implementation requires caller to check !empty() first: 

    // returns: value of the first non-head node 
    // if the list is empty, undefined behavior. 
    int front() 
    { 
     return head->next->x; 
    } 

    // alternatively: 

    // returns: value of the first non-head node or -1 if the list is empty. 
    int front_safe() 
    { 
     return (head->next) ? head->next->x : head->x; 
    } 
}; 

int main() 
{ 
    LinkedList lt; 
    lt.add(1); 
    lt.add(2); 
    lt.add(3); 
    lt.add(4); 
    cout << lt.front() << endl; 
    cout << lt.back() << endl; 
} 

Live-Demo: http://ideone.com/UzYCii

Anstatt mit C++ Vermächtnis rohen Zeiger zu tun, ich möchte Sie ermutigen, weiter zu lernen, über std::unique_ptr: eine Standard-Bibliothek-Objekt, das mit dem Eigentum von Zeigern befasst. Wenn ein std::unique_ptr den Gültigkeitsbereich verlässt, wird der Speicher (falls vorhanden), auf den er verweist, automatisch freigegeben. Dies schließt ein, wenn der unique_ptr ein Mitglied einer Instanz ist, die weggeht oder gelöscht wird.

http://en.cppreference.com/w/cpp/memory/unique_ptr

+0

Vielen Dank! Ich nehme deinen Rat und lerne über diese Hinweise, alles, was du sonst noch empfehlen kannst? – pitar

+0

@pitar Die Standardbibliothek ist ein Hauptteil von modernem C++. Ich möchte Sie ermutigen, sich mit Klassen wie 'std :: list',' std :: vector', 'std :: array' vertraut zu machen. Aber das Schreiben eigener Implementierungen als Lernübung kann auch unglaublich wertvoll sein - nicht nur um zu verstehen, wie sie funktionieren, sondern auch, um Ihr Verständnis der Sprache und der Sprach- und Algorithmuskonzepte zu verbessern. – kfsone