2009-05-18 4 views
2

C++의 이진 검색 트리 구현과 관련하여 질문이 있습니다. 다음은 질문입니다.이진 검색 트리

정수를 저장하는 간단한 (템플리트가 아닌) BST를 구현하십시오. Insert, Remove, inOrder traversal, preOrder traversal, postOrder traversal과 같은 작업을 제공합니다.

트리를 처리하는 데 재귀 루틴을 사용하십시오.

노드를 처리하는 것은 노드의 내용을 인쇄하는 것으로 간단히 노드에 저장된 정수입니다.

데이터는 테스트 파일에서 가져와야합니다. 주 프로그램은 데이터 파일을 열고 트리에 삽입하고 다른 트리 작업을 보여줘야합니다.

이 연습의 요점은 BST를 이해한다는 것을 입증하는 것입니다. 그것과 함께 배를 타고 묻지 않은 작업을 할 필요가 없습니다.

지금까지 헤더 파일을 만들었습니다. 누구든지 내 생각에 올바른 방향으로 가고 있는지 조언 해 주시겠습니까?

using namespace std; 
#ifndef BSTNODE_H 
#define BSTNODE_H 
class BSTNode 
{ 
    private: 
    //Defines the 'node' structure 
    struct tree_node 
    { 
    tree_node *left; // left subtree has smaller elements 
    tree_node *right; // right subtree has larger elements 
    int m_data; 
    }; 
    //root * r; 
    public: 
     //The Constructor 
     BSTNode(); 
     //The Destructor 
     ~BSTNode(); 
     //Inserts a value into a BST, public function 
     void insert(const m_data & d); 
     //Removes a value from a BST, public function 
     void remove(const m_data & d); 
     //isEmpty function, public function 
     bool isEmpty(); 
     BSTNode getData(); 
     void inOrder(const m_data & d); 
     void preOrder(const m_data & d); 
     void postOrder(const m_data & d); 
}; 
#endif 

다음으로 BSTNode.cpp 파일을 만들어야합니다. [email protected]으로 메일을 통해 귀하의 답변을 감사드립니다. 미리 감사드립니다.

+0

순회 함수를 반복자로 구현해야합니까 ...? 나는 C++ 컨벤션을이 질문에 대한 대답으로 추가 할 수있을만큼 잘 모른다. – CookieOfFortune

+1

절대로 넣지 마십시오 : using namespace std; 헤더 파일에. –

답변

3

당신은 typedef는 다양한 방법으로 사용하고있는 유형 m_data에 잊어 버린 것, 그리고 당신이 별도의 tree_node 구조체를 원하는 이유를 이해하지 않습니다 (자체보다는 클래스를 사용하여?)도 왜 getData는해야 int 대신 BSTNode을 반환하십시오.

3
//Inserts a value into a BST, public function 
    void insert(const m_data & d); 
    //Removes a value from a BST, public function 
    void remove(const m_data & d); 
    //isEmpty function, public function 
    bool isEmpty(); 
    BSTNode getData(); 
    void inOrder(const m_data & d); 
    void preOrder(const m_data & d); 
    void postOrder(const m_data & d); 

m_data는 (는) 형식이 아닌 구성원입니다. 여기서 int를 사용해야합니다. 또한 노드가 tree_node이므로 외부 클래스는 트리 전체를 나타낼 수 있습니다 (예 : BSTree가 BSTNode가 아님).

또한 'using namespace std;' 헤더에서 악의적 인 것입니다. 헤더를 포함하지 않는 것을 선택해야만합니다. 이 파일을 사용하려면 .cpp 파일로 보관하는 것이 좋습니다.

+0

'네임 스페이스 표준을 사용하는 것'이 필요하지는 않습니다. 헤더에 - 내가 볼 수있는 것은 아무것도 없습니다. 구현에 따라 달라지는 –

1

BST에 대한 고전적인 질문 - 데이터 구조에 대한 훌륭한 책은 전체 코드를 제공합니다. 다음 페이지에는 C++ http://cslibrary.stanford.edu/110/BinaryTrees.html의 코드 예제가 포함되어 있습니다.

순회 함수는 BST 클래스 자체의 일부가 아니어야하며, BSTNode는 왼쪽/오른쪽 노드 포인터를 노출해야합니다. 호출하는 응용 프로그램은 특정 방식으로 호출해야합니다. 또는 콜백 함수를 사용하고 클래스 내에서 트래버스 코드를 제공하면 훨씬 더 깔끔해질 것입니다.

1

커플 일 - 다른 사람이 지적한 것처럼, 당신은

void insert(const int & d); 
//Removes a value from a BST, public function 
void remove(const int & d); 
//isEmpty function, public function 
bool isEmpty(); 
BSTNode getData(); 
void inOrder(const int & d); 
void preOrder(const int & d); 
void postOrder(const int & d); 

다른 일을 사용해야합니다 당신이 당신의 루트 노드를 주석 한 것입니다. 잘못 정의했지만 루트 노드를 클래스에 포함시켜야합니다.올바른 정의는 이전에 지적 된 바와 같이, 네임 스페이스 표준을 사용하여

를 제거, 또한

tree_node *root; 

것;

헤더 파일에서 대신 구현 파일에 넣습니다.

내가 지금 볼 수있는 전부입니다.

1

또 다른 문제점은 지정된 클래스가 중첩 형식 및 메서드를 선언하지만 멤버 데이터가 없음을 나타냅니다.


이터레이터를 사용하여 순회 기능을 선언 할 수 있습니다. 예 : preorder 메소드는 노드에 대해 참조 해제 할 수있는 중개자를 리턴하거나 선행 순서에서 다음 노드를 가리 키도록 증가시킵니다.

또는 콜백을 사용하여 순회 기능을 선언 할 수 있습니다. 즉, 호출자가 콜백 인스턴스를 preorder 메소드에 전달하고 preorder 메소드가 트리를 가로 지르고 각 노드의 콜백 메소드를 호출합니다. 콜백 메소드는 노드 더 구체적으로는 노드 데이터)를 매개 변수로 사용하여 콜백이 호출을 이상 종료하려는 것으로 명시 할 수있는 부울을 반환 할 수 있습니다.

1

검색 방법도 추가 할 것입니다.

bool search(int whatIlookfor); 

또는 또한, 안전한 장소에 tree_node *root을 유지

tree_node* search(int whatIlookfor); 

더 나은. 사소한

2

예시 : 일반적

tree_node *left; // left subtree has smaller elements 

는 좌측 서브 트리 또한 동일한 요소를 포함한다. 귀하의 예제에서 구조체 타입의 왼쪽과 오른쪽 포인터를 사용

+0

이진 검색 트리에서 노드가 중복되지 않도록 즉시 포함시키지 않을 수도 있습니다. –

+0

사실입니다. 구현에 따라 다릅니다. 그러나, 나는 OP가 그가 아직 없다면 동등한 요소를 삽입하는 것에 관심을 가져야한다고 지적하고 싶었습니다. – Donotalo

1
  • 는 유연성을 모두를 제한하는 것 -이 새로운 서브 트리에 대한 작업을 호출 할 다음 BST을 루트의 왼쪽 아이를 통과하고, 가정합니다. 포인터는 구조체 유형이므로 사용할 수 없습니다. 차라리 두 포인터를 BSTNode 유형으로 사용할 것을 제안합니다. 포인터가 어쨌든 뿌리를 가리 킵니다 주에서 개체를 참조하는 데 사용하기 때문에

    BSTNode *right;

    BSTNode *left; 또한, 루트 문제 (필수 명시적인 루트 포인터를) 해결할 것입니다.

  • traversal 함수는 본질적으로 전체 트리를 가로 지르고 모든 데이터 항목을 인쇄 할 때 어떤 인수도 필요하지 않습니다. 데이터 항목은 다른 검색 멤버 함수에 전달되어 TrueStar가 이미 지적한 위치를 검색 할 수 있습니다.

  • 나는 또한 공개 멤버 함수의 복잡성을 줄일 수있는 몇 가지 개인 멤버 함수 제안
  • (DeleteNodeCaseB(int data) 다시 시간 내에서 DeleteNodeCaseA(int data)를 호출 것) -

    BSTNode * setleft(int data);

    BSTNode * setright(int data);

    void DeleteNodeCaseA(int data)/* 하나 또는 양쪽 모두가 존재하지 않습니다. */

    void DeleteNodeCaseB(int data)/*가 모두 왼쪽과 오른쪽 자식 */

1

당신이 C++를 사용하고 있기 때문에, 당신은 몇 가지 표준 라이브러리를 사용하는 대신에 모든 자신을 구현하기 위해 노력하는 것이 좋습니다? STL 라이브러리에는 응용 프로그램에 더 적합한 레드 - 블랙 트리가 있습니다. 이진 트리는 겹쳐서 표시되거나 링크 목록으로 변질 될 수 있습니다.

추신 : 물론 숙제를하지 않는다고 가정합니다.