2010-12-02 22 views
2

Ich arbeite an einem B-Baum (oder ist es BTree?) Für eine Klasse, die ich derzeit nehme. Ich habe das meiste davon richtig umgesetzt (glaube ich). Allerdings habe ich Probleme, eine Inorder-Traversierung zu finden. Hier ist meine Hauptfunktion:Inorder Traversal eines B-Baumes (C++)

Also ich bin ein 5-Wege-Baum, der Zeichen enthält. Ich füge jeden der Zeichen in den Baum ein und zeige dann den Invers-Durchlauf für jede Iteration zu Debugging-Zwecken an. Dies ist die Ausgabe erhalte ich:

0: a 
1: ag 
2: afg 
3: abfg 
4: abffgk 
5: abdgfgk 
6: abdgfghk 
7: abdgfghkm 
8: abdgfghjjkm 
9: abdefghjjkm 
10: abdefghjjkms 
11: abdefghimjkms 
12: abdefghimjkmrs 
13: abdefghimjkmrrsx 
14: abccdefghimjkmrrsx 
15: abccdefghimjklmsrsx 
16: abccdefghimjklmnrsx 
17: abccdefghimjklmnrstx 
18: abccdefghimjklmnrstux 
19: abccdefghimjjklmmnprstux 

In fast alle von ihnen, einige der Zeichen dupliziert werden, aber nicht konsequent zwischen Einfügungen, so ist es (für mich) scheint nicht, wie doppelte Daten zu bekommen. ich kann nicht Sinn zu machen scheinen, aber hier ist meine inorder Methode:

template <class Record, int order> 
void Tree<Record, order>::inorder() 
{ 
    inorder(root); 
} 

template <class Record, int order> 
void Tree<Record, order>::inorder(Node<Record, order> *current) 
{ 
    for (int i = 0; i < current->count+1; i++) { 
     if (current->branch[i]) 
      inorder(current->branch[i]); 
     if (i < order-1 && current->data[i]) 
      cout << current->data[i]; 
    } 
} 

in meinem Knoten Implementierung Zahl ist die Anzahl von ‚Daten‘ (jedes Zeichen) im Baum. count + 1 wäre, wie viele Zweige aus dem Knoten für die Nicht-Blattknoten kommen. branch ist ein Array des nächstniedrigeren Knotensatzes, data ist ein Array der chars.

Hier ist meine Knoten Implementierung:

template <class Record, int order> 
struct Node 
{ 
    int count; 
    Record data[order - 1]; 
    Node<Record, order>* branch[order]; 
    Node() : count(0) {} 
}; 

Hier ist alles verwendet, einfügen:

template <class Record, int order> 
ErrorCode Tree<Record, order>::insert(const Record& new_entry) 
{ 
    Record median; 
    Node<Record, order> *right_branch, *new_root; 
    ErrorCode result = push_down(root, new_entry, median, right_branch); 

    if (result == overflow) { 
     new_root = new Node<Record, order>(); 
     new_root->count = 1; 
     new_root->data[0] = median; 
     new_root->branch[0] = root; 
     new_root->branch[1] = right_branch; 
     root = new_root; 
     result = success; 
    } 

    return result; 
} 

template <class Record, int order> 
ErrorCode Tree<Record, order>::push_down(
       Node<Record, order> *current, 
       const Record &new_entry, 
       Record &median, 
       Node<Record, order> *&right_branch) 
{ 
    ErrorCode result; 
    int position; 

    if (current == NULL) { 
     median = new_entry; 
     right_branch = NULL; 
     result = overflow; 
    } 
    else { 
     if (search_node(current, new_entry, position) == success) 
      result = duplicate_error; 
     else { 
      Record extra_entry; 
      Node<Record, order> *extra_branch; 
      result = push_down(current->branch[position], new_entry, 
           extra_entry, extra_branch); 
      if (result == overflow) { 
       if (current->count < order - 1) { 
        result = success; 
        push_in(current, extra_entry, extra_branch, position); 
       } 
       else 
        split_node(current, extra_entry, extra_branch, position, 
           right_branch, median); 
      } 
     } 
    } 

    return result; 
} 

template <class Record, int order> 
void Tree<Record, order>::push_in(Node<Record, order> *current, 
       const Record &entry, 
       Node<Record, order> *right_branch, 
       int position) 
{ 
    for (int i = current->count; i > position; i--) { 
     current->data[i] = current->data[i-1]; 
     current->branch[i+1] = current->branch[i]; 
    } 

    current->data[position] = entry; 
    current->branch[position+1] = right_branch; 
    current->count++; 
} 
+0

Bitte zeigen Sie uns die Node-Datenstruktur - ich verstehe nicht, warum 'branch' scheinbar' count + 1' Elemente lang ist. Die Struktur zu zeigen ist klarer als zu versuchen, sie zu beschreiben. Was steuert der Template-Parameter 'order'? –

+0

Der Parameter der Auftragsvorlage steuert, in welcher Reihenfolge ein Baum arbeitet, mit dem wir arbeiten. In diesem Fall ein 5-Wege-Baum (Baum * Baum = neuer Baum ). Hinzufügen von Knoten jetzt .... – gregghz

+0

@ greggory.hz können Sie klären, was "count" bedeutet? Ist es die Anzahl der Zweige, die hinzugefügt wurden? oder die Anzahl der 'Daten' Elemente? oder etwas anderes? Ich denke, es könnte einen Fehler geben, wie count verwendet wird, aber es ist schwer zu sagen, ohne zu wissen, wie 'insert' es benutzt. – MerickOWA

Antwort

1

Heh, ich denke, dass wir in der gleichen Klasse sind. Ich habe gerade meins beendet, und ich sah das Problem in Ihrem Inorder Traversal, auch mit dem Neuen. In diesem zweiten, wenn:

if (i < order-1 && current->data[i]) 
cout << current->data[i]; 

es tut es für den Auftrag, nicht, wie viele Daten zur Zeit im Knoten, so, es wird ein gewisses Extra auszuspucken. Ich habe es in i<current->data geändert und jetzt funktioniert es gut. ^^ b Gerade fertig. Wenn es für dich nicht funktioniert, sorry. ^^;

+0

So mit i < current-> Daten, bekomme ich einen Compiler-Fehler ... da ich ein int und current-> Daten ist ein Zeiger (Array) ist. Sie haben mich jedoch in die richtige Richtung gewiesen. Ich änderte es zu i < current-> zählen und es hat perfekt funktioniert! Danke für die Hilfe :) (vielleicht bearbeiten Sie Ihre Antwort, um die Änderung zu reflektieren, die ich gemacht habe) – gregghz

1

Ihr Problem ist, dass Ihre for-Schleife von 0 wird zählen (einschließlich), aber Ihr Knoten: : Daten-Array ist nicht definiert bei Daten [count] es ist nur bis zu Daten [count-1] definiert, so dass die letzte Iteration Ihrer Schleife immer Müll bekommt, der manchmal nicht Null ist und nicht angezeigt wird, aber manchmal auch mal zufällige Zeichen.

Sie müssen Sonderfall Code für, wenn "i == Ordnung" wie so

if (current->branch[i]) 
    inorder(current->branch[i]); 
if (i < order-1 && current->data[i]) 
    cout << current->data[i]; 
+0

Wenn ich das +1 aus der for-Schleife nehme, werden nicht immer alle Zeichen gedruckt. In Iteration 4 bekomme ich 'abf' und in Iteration 19 zum Beispiel 'abcdefj'. Die meisten (nicht alle) der anderen Iterationen sind ähnlich kurz, aber diese beiden sind am einfachsten auf einen Blick zu stoppen. – gregghz

+1

@ greggory.hz Ihr Code für inorder geht davon aus, dass er mit 'i' sowohl auf das Zweigarray als auch auf das Datenarray zugreifen kann. Wenn count = 4 ist, greifen Sie auf eine ungültige Position in den Daten zu Zweigstelle. – MerickOWA

+0

@ greggory.hz Versuchen Sie den aktualisierten Code – MerickOWA