2017-03-22 2 views
1

J'ai édité un code pour un arbre de recherche binaire, pour des chaînes. Mais il y a un petit problème. Lorsque j'entre une entrée simple comme A B C D E F, mon programme dit que le formulaire de pré-commande est A B C D E F ... ce qui devrait être A B D E C F.Pourquoi mon code ne fera-t-il pas le formulaire de précommande correctement dans l'arbre de recherche binaire?

Depuis, il faut imprimer le mot à la racine puis imprimez le mot à la sous-arborescence à gauche en pré-commande, puis imprimer le mot à le sous-arbre droit en pré-commande.

Publier devrait également imprimer D E B F C A mais il imprime A B C D E F et en ordre devrait avoir imprimé D B E A F C ... mais il m'a donné F E D C B A.

Toute aide est appréciée, je ne sais pas ce qui s'est mal passé.

Voici le code source complet de travail:

#include <iostream> 
#include <string> 
#include <conio.h> 
using namespace std; 

class Node { 
string word; 
Node* left; 
Node* right; 
public: 
Node() { word=-1; left=NULL; right=NULL; }; 
void setWord(string aWord) { word = aWord; }; 
void setLeft(Node* aLeft) { left = aLeft; }; 
void setRight(Node* aRight) { right = aRight; }; 
string Word() { return word; }; 
Node* Left() { return left; }; 
Node* Right() { return right; }; 
}; 

class Tree { 
Node* root; 
public: 
Tree(); 
~Tree(); 
Node* Root() { return root; }; 
void addNode(string word); 
void inOrder(Node* n); 
void preOrder(Node* n); 
void postOrder(Node* n); 
private: 
void addNode(string word, Node* leaf); 
void freeNode(Node* leaf); 
}; 

Tree::Tree() { 
root = NULL; 
} 

Tree::~Tree() { 
freeNode(root); 
} 

void Tree::freeNode(Node* leaf) 
{ 
if (leaf != NULL) 
{ 
    freeNode(leaf->Left()); 
    freeNode(leaf->Right()); 
    delete leaf; 
} 
} 

void Tree::addNode(string word) { 
if (root == NULL) { 
    Node* n = new Node(); 
    n->setWord(word); 
    root = n; 
} 
else { 
    addNode(word, root); 
} 
} 

void Tree::addNode(string word, Node* leaf) { 
if (word <= leaf->Word()) { 
    if (leaf->Left() != NULL) 
     addNode(word, leaf->Left()); 
    else { 
     Node* n = new Node(); 
     n->setWord(word); 
     leaf->setLeft(n); 
    } 
} 
else { 
    if (leaf->Right() != NULL) 
     addNode(word, leaf->Right()); 
    else { 
     Node* n = new Node(); 
     n->setWord(word); 
     leaf->setRight(n); 
    } 
} 
} 

void Tree::inOrder(Node* n) { 
if (n) { 
    inOrder(n->Left()); 
    cout << n->Word() << " "; 
    inOrder(n->Right()); 
} 
} 

void Tree::preOrder(Node* n) { 
if (n) { 
    cout << n->Word() << " "; 
    preOrder(n->Left()); 
    preOrder(n->Right()); 
} 
} 


void Tree::postOrder(Node* n) { 
if (n) { 
    postOrder(n->Left()); 
    postOrder(n->Right()); 
    cout << n->Word() << " "; 
} 
} 

int main() { 
string word; 
Tree* tree = new Tree(); 
while(word != "end"){ 
    cin >> word; 
    if(word == "end"){ 
     break; 
    } 
    tree->addNode(word); 
} 

cout << "In order traversal" << endl; 
tree->inOrder(tree->Root()); 
cout << endl; 

cout << "Pre order traversal" << endl; 
tree->preOrder(tree->Root()); 
cout << endl; 

cout << "Post order traversal" << endl; 
tree->postOrder(tree->Root()); 
cout << endl; 

delete tree; 
_getch(); 
return 0; 
} 
+0

Débogueur. Utilisez un débogueur. Un débogueur vous permettra d'exécuter chaque instruction, une à la fois, et * regarder * les valeurs des variables. Modifiez votre publication avec des détails sur l'instruction suspecte, après avoir utilisé le débogueur. –

+0

Salut @ThomasMatthews Je ne suis pas sûr de savoir comment utiliser un débogueur. Existe-t-il un moyen natif de déboguer dans l'édition Visual Studio C++ Express? Merci pour votre réponse. –

Répondre

1

Dans votre exemple de test A B C D E F votre arbre est essentiellement une liste chaînée. Tout d'abord, vous insérez A, il devient ainsi votre nouvelle racine. B est plus grand que A, donc quand vous l'insérez, il va comme un enfant droit. La même chose se produit pour toutes les chaînes suivantes:

A ->B ->C ->D ->E ->F.

Ainsi, lorsque vous traversez votre arbre à partir de la gauche, vous imprimez simplement votre liste telle qu'elle est car il n'y a aucun enfant à gauche dans l'un des nœuds de l'arbre. Lorsque vous le traversez depuis la droite, il vous suffit de l'imprimer en arrière.

Étant donné que votre arbre est déséquilibré, il s'agit d'un comportement attendu. Il n'y a pas de bugs dans votre code à partir de ce que je peux voir. Essayez d'ajouter un équilibre ou faites une autre racine.

+0

Comment puis-je faire un arbre sans trier alors? Parce que quand j'essaie tout ce que je reçois en sortie, c'est des choses bizarres, comme 'A' ou' A F F'. Ne fonctionne pas correctement. –

+0

C'est un arbre. Même une liste liée est techniquement un arbre. Si vous demandez comment faire un arbre * équilibré * (arbre avec la hauteur maximale de log (n)), alors vous devez implémenter l'équilibrage pour votre arbre (google it). Je ne comprends pas ce que vous voulez dire par «faire un arbre sans trier»? Vous avez déjà implémenté un arbre de recherche binaire fonctionnel. Si vous voulez juste un arbre dont la hauteur est toujours en log (n), jetez un oeil à "heap (structure de données)", mais l'arborescence de tas n'est pas un arbre de recherche binaire. –

+0

Je voulais dire, si je veux créer un arbre comme ça: https://d2vlcm61l7u1fs.cloudfront.net/media%2F991%2F99188ce0-2ecc-478e-93b3-ada532011ac0%2Fphpstal8r.png Que dois-je faire? Sans faire B aller à droite, C à droite, D à droite etc ... Tout devrait apparaître comme celui de l'image. Je ne le fais pas. –