2017-03-22 17 views
1

문자열 용 이진 검색 트리에 대한 코드를 편집했습니다. 그러나 작은 문제가 있습니다. A B C D E F와 같은 간단한 입력을 입력하면 예약 주문 양식이 A B C D E F ...이고 실제로는 A B D E C F이어야합니다. 그 다음 루트에있는 단어를 인쇄 예약 주문의 왼쪽 서브 트리에있는 단어를 인쇄 한 후 에서 예약 주문의 오른쪽 서브 트리를 단어를 인쇄해야하기 때문에내 코드가 바이너리 검색 트리에서 사전 주문 양식을 올바르게 수행하지 않는 이유는 무엇입니까?

.

후 주문도 D E B F C A를 인쇄하지만 A B C D E F을 인쇄하고에 주문 D B E A F C를 인쇄해야했습니다 ...하지만 그냥 나에게 F E D C B A을 준해야한다.

도움이되었는데, 무엇이 잘못되었는지는 모르겠다.

#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

디버거. 디버거를 사용하십시오. 디버거를 사용하면 각 문을 한 번에 하나씩 실행하고 변수의 * watch * 값을 실행할 수 있습니다. 디버거를 사용한 후 의심스러운 성명에 대한 세부 정보와 함께 게시물을 편집하십시오. –

+0

안녕하세요 @ ThomasMatthews 나는 디버거를 사용하는 방법에 대해 확실히 모르겠습니다. Visual Studio C++ Express 버전에서 디버깅 할 수있는 기본 방법이 있습니까? 답장을 보내 주셔서 감사합니다. –

답변

1

테스트 예에서 A B C D E F 당신의 나무가 기본적으로 링크 된 목록입니다 : 여기

는 작업 전체 소스 코드입니다. 먼저 A을 삽입하여 새로운 루트가됩니다. BA보다 커서 삽입 할 때 올바른 아이가됩니다. 동일은 다음의 모든 문자열을 발생합니다

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

왼쪽에서 트리를 탐색 할 때 트리의 노드에 왼쪽 자식이 없으므로 그대로 목록을 인쇄합니다. 오른쪽에서 그것을 가로 지르면 바로 뒤쪽으로 인쇄합니다.

트리가 불균형이므로 예상되는 동작입니다. 내가 볼 수있는 코드에는 버그가 없습니다. 균형 조정을 추가하거나 다른 루트를 만들어보십시오.

+0

어떻게 정렬하지 않고 트리를 만들 수 있습니까? 왜냐하면 내가 노력할 때 'A'나 'A F F'와 같은 이상한 것들이 산출물로 나온다. 제대로 작동하지 않습니다. –

+0

나무입니다. 연결된 목록조차 기술적으로 나무입니다. 밸런스 * 트리 (log (n)의 최대 높이를 가진 트리)를 만드는 방법을 묻는다면 트리 (Google)의 밸런싱을 구현해야합니다. 나는 '정렬하지 않고 나무 만드십시오'라는 뜻을 이해하지 못합니까? 이미 이진 검색 트리를 구현했습니다. log (n) 높이의 트리를 원한다면 "heap (data structure)"를 살펴 보라. 그러나 heap tree는 바이너리 검색 트리가 아니다. –

+0

그런 나무를 만들고 싶다면 https://d2vlcm61l7u1fs.cloudfront.net/media%2F991%2F99188ce0-2ecc-478e-93b3-ada532011ac0%2Fphpstal8r.png 어떻게해야합니까? B를 오른쪽으로, C를 오른쪽으로, D를 오른쪽으로 이동하지 않고 ... 모두가 이미지의 것과 같이 나타나야합니다. 나는 그것을하지 못한다. –