2014-12-02 11 views
6

Ich erstelle also eine Klasse, die eine Adjazenzliste implementiert. Derzeit in meiner Klasse Definition initialisiert ich zwei Vektoren:Einfügen von Elementen in 2D-Vektor

vector<vector<int>> adjList; 
vector<int> neighbors; 

und ich erklärte zwei Funktionen, die ich plane, zu verwenden, um es zu machen:

bool constructAdjList(); 
bool insertIntoAdjList(int, int); 

Es wird schwierig Einwickeln meinen Kopf um 2D-Vektoren. Ich verstehe, dass es im Wesentlichen ein Vektor von Vektoren ist, aber ich bin verwirrt darüber, wie man einen neuen Wert in einen der "Subvektoren" einfügt. Zum Beispiel, kann ich eine Adjazenzliste in createAdjList erstellen, die mit der folgenden Schleife leer ist:

for (int i = 0; i < numOfValues; i++){ 
    neighbors.push_back(0); 
    adjList.push_back(neighbors); 
    neighbors.clear(); 
} 

Aber wie kann ich sagen, push_back den Wert 5 bis 4. Vektor in adjList, die dargestellt werden würden meine insertIntoAdjList Funktion als

insertIntoAdjList(4, 5); 

ich weiß, dass ich einen bestimmten Wert in einem Vektor 2D zugreifen kann, indem er sagte adjList [4] [1], aber wie kann ich eine auf ihn schieben?

Danke!

+0

Ich verstehe es nicht, kannst du das nicht tun: 'adjList [4] [1] = 987'? – Kam

+0

Das funktioniert, wenn ich bereits einen Wert in der [4] [1] Position habe, aber wenn ich eigentlich einen Wert auf das Ende von Vektor 4 schieben möchte, muss ich irgendwie push_back? –

+0

Ich denke, eine 'std :: unordered_map >' kann Ihnen besser dienen. nur meine Meinung. – WhozCraig

Antwort

10

auf dem Vektor zu drücken, die ein Element eines anderen Vektors, sind Sie einfach diesen

adjList[x].push_back(); 
+0

Oh wow, ich wusste nicht, dass Sie nur eine der Koordinaten im 2D-Vektor angeben können. Das macht es viel einfacher, danke! –

+4

@Mardo Ich denke, es ist wichtig zu verstehen, dass 'adjList [x]' einen Verweis auf den Vektor zurückgibt, der an der Position 'x' gespeichert ist.Also, 'adjList [x] [y]' ist das gleiche wie '(adjList [x]) [y]' und bedeutet: Gib mir zuerst einen Bezug auf den Vektor an der Position 'x' in' adjList' (rufen wir an es V), dann geben Sie mir einen Bezug auf die ganze Zahl an der Position "y" in V. – Lemming

1

Ein paar Hinweise hier.

können Ihre Schleife deutlich nur die Konstrukteure Ihrer beiden Mitglieder verwenden verkürzt werden:

vector<int> neighbors(1, 0); // set to length 1, value is zero 
vector<vector<int>> adjList(numOfValues,neighbors); // "outer" vector is numOfValues long 
.             // each row is a *COPY* of neighbor 

Wenn Sie nicht diese bei Bauzeit tun (numOfValues ​​vielleicht ist noch nicht bekannt), dann gibt es immer noch

// neighbors object can be reused 
neighbors.clear(0); 
neighbors.push_back(0); 
adjList.reserve(numOfValues); // reserving memory ahead of time will prevent allocations 
for (int i = 0; i < numOfValues; i++){ 
    adjList.push_back(neighbors); // push_back is by *COPY* 
} 

In Ihrem Beispiel durch klare Verwendung und push_back im wesentlichen den gleichen Vektor, Sie sind riskieren eine Zuordnung jedes Schleifeniterationslatenzzeit zu bauen und jeder es Freigabe: eine bessere Schleife Phrasierung können wir verwenden eration. In der Praxis werden die meisten Implementierungen das nicht tun, aber wenn wir beides verkürzen und möglicherweise die Dinge effizienter machen können, können wir das auch.

Schließlich, wenn die Anzahl der Nachbarn ist relativ klein und ähnlich Zeile für Zeile (zum Beispiel eine finite Elemente Code mit Tetraeder-Elementen, wo jedes Element verbindet ~ 5 andere), dann wie Sie andere vorgeschlagen haben, könnte besser dran sein mit einer anderen Struktur als Vektor-Vektor. Zum Beispiel ein einzelner Vektor, der logisch so organisiert ist, dass eine neue "Zeile" jedes N Elemente beginnt.

Verwandte Themen