2016-07-14 17 views
1

Ich habe einen einfachen Algorithmus, der eine Liste von Listen zurückgibt, wobei jede innere Liste die Knoten auf einer anderen Ebene eines Binärbaums enthält. Ich habe Probleme zu verstehen, wie ich den Umfang meiner inneren Liste "zurücksetzen" kann (z. B. siehe unten).Umfang eines Objekts in einer Schleife

Mein Baum ist ein einfaches Spielzeug Baum wie so:

struct Node { 
    int data; 
    Node *left, *right; 
} 

Ich benutze eine einfache bfs, die eine Liste von Listen zurückgeben sollen. Ich versuche, eine neue Liste auf jeder der Schleifen zu erstellen, aber ich bin nicht sicher, wie man die Liste "löscht" und eine neue beginnt.

std::vector< std::vector<Node *> > build_lists(Node *root) { 
    std::vector< std::vector<Node *> > result; 

    Node *newline = new Node { std::numeric_limits<int>::min(), nullptr, nullptr }; 

    std::deque<int> q; 
    q.push_back(root); 
    q.push_back(newline); 


    Node *tmp; 
    std::vector<Node *> inner; // HERE IS WHERE IS SET THE FIRST INNER VECTOR 
    while(!q.empty()) { 
     tmp = q.front(); 
     q.pop_front(); 
     if (tmp == newline) { 
      result.push_back(inner); 
      std::vector<Node *> inner; // HERE IS WHERE I TRY TO ''RESET'' THE VECTOR 
      if (!q.empty()) 
       q.push_back(newline); 
     } else { 
      inner.push_back(tmp); 
      if (tmp->left) 
       q.push_back(tmp->left); 
      if (tmp->right) 
       q.push_back(tmp->right); 
     } 
    } 
} 

Offensichtlich habe ich nicht verstanden, Umfang und einige grundlegende Sprachfunktionen. Wenn mir jemand helfen könnte, mich in die richtige Richtung zu lenken, würde ich es begrüßen.

+0

Hat nicht abgestimmt. Mit Liste meinst du "inner"? – gsamaras

+0

@gsamaras ja. Entschuldigung, Vektor, denke ich hier. –

+0

Das Deklarieren eines zweiten Objektnamens "inner" führt zum ersten Objekt nichts aus - es bedeutet nur, dass Sie zwei Objekte auf dem Stapel mit demselben Namen haben (eine Sache, die in C++ erlaubt ist, aber allgemein als verpönt angesehen wird) wird Verwirrung stiften). Um den Vektor zurückzusetzen, sollten Sie stattdessen inner.clear(); –

Antwort

2

Sie können eine Variable nicht zurücksetzen, indem Sie sie erneut deklarieren, was Ihr Code tut. Sie haben nun eine zweite Variable mit demselben Namen, die für die Dauer der zweiten Variablen diesen Namen auf die zweite Variable zeigt.

Stattdessen müssen Sie eine Methode verwenden, um die erste Variable zu löschen.

vector hat eine method to reset it's contents - vector::clear.

Sie sollten diese stattdessen tun:

result.push_back(inner); 
// std::vector<Node *> inner; 
inner.clear(); 

Wenn Sie etwas löschen müssen Sie in einem Vektor gedrückt haben, können Sie dies tun:

vector< vector<int> > vvi; 
vector<int> vi; 
vi.push_back(1); // fill 
vii.push_back(vi); // vii has a copy of vi as it is now. 
auto & _v = vii[0]; // fetch a reference to the copy 
_v.clear(); // clear it 
vii[0].clear(); // same in one step 
assert(vii[0].size() == 0); // still contains a vector at index 0 but it's empty 

Ungeachtet der Tatsache, dass Sie würden Vektoren von Zeiger löschen - wie andere darauf hingewiesen haben (ha) müssen Sie sehr vorsichtig sein, nicht die Spur von Zeigern zu verlieren.

Eg, wäre dies schlecht sein:

vector< int* > x; 
x.push_back(new int(4)); 
x.clear(); // leak 
0

Um ein Objekt außerhalb des Gültigkeitsbereiches zu gehen, es muss INSIDE die Schleife erzeugt werden, wie dies zum Beispiel:

while(1) { 
    std::vector<int> v; 
    ... 
    // at that point 'v' will go out of scope and thus destroyed 
} 

wenn Sie jedoch dies tun:

std::vector<int> v; 
while(1) { 
    ... 
    // 'v' is always the same at this point 
} 

Sie könnten std::vector::clear() verwenden, um Ihren Vektor zurückzusetzen, aber seien Sie vorsichtig, da Sie Zeiger verwenden. Wenn Sie nicht die spitzen Objekte verfolgen, würde das Löschen des Vektors nur zu dangling pointer führen, also Undefined Behavior und Sie wollen nicht, dass das passiert.

Wenn Sie den Speicher die Zeiger weisen auf befreien, dann sollten Sie ersten die Objekte, um den Zeiger Punkt löschen zu und dann klar den Vektor.