학교 과제

c++로 작성한 이진탐색트리

꾸준함. 2018. 1. 5. 17:19

자료구조 프로그래밍 과목을 배우면서 c++로 작성한 이진탐색트리입니다.


bst.in

bst.in2

bst.h

#ifndef BST_H

#define BST_H

 

#include <iostream>

#include <string>

#include <queue>

using namespace std;

 

template <class K, class E>

struct Node

{

        Node(K ky, E el, Node<K, E> *left = 0, Node<K, E> *right = 0) :key(ky), element(el), leftChild(left), rightChild(right)

        {

        }

        Node<K, E> *leftChild;

        K key;

        E element;

        Node<K, E> *rightChild;

};

 

template <class K, class E>

class BST

{

private:

        void Visit(Node<K, E> *);

        void Insert(Node<K, E>*&, K &, E &);

        void Delete(Node<K, E>*&, K &);

        void Preorder(Node<K, E> *);

        void Inorder(Node<K, E> *);

        void Postorder(Node<K, E> *);

        Node<K, E> *root;

public:

        BST()

        {

               root = 0;

        }

        void Insert(K &newkey, E &el)

        {

               Insert(root, newkey, el);

        }

        void Delete(K &oldkey)

        {

               Delete(root, oldkey);

        }

        bool Find(const K &, E &);

        void Preorder()

        {

               Preorder(root);

        }

        void Inorder()

        {

               Inorder(root);

        }

        void Postorder()

        {

               Postorder(root);

        }

        void Levelorder();

};

 

template <class K, class E>

void BST<K, E>::Visit(Node<K, E> *ptr)

{

        cout << ptr->key << ":" << ptr->element << " ";

}

 

template <class K, class E>

void BST<K, E>::Insert(Node<K, E> *&ptr, K &newkey, E &el)

{

        if (ptr == 0)

               ptr = new Node<K, E>(newkey, el);

        else if (newkey < ptr->key)

               Insert(ptr->leftChild, newkey, el);

        else if (newkey>ptr->key)

               Insert(ptr->rightChild, newkey, el);

        else

               ptr->element = el;

}

 

template <class K, class E>

bool BST<K, E>::Find(const K &k, E &e)

{

        Node<K, E> *ptr = root;

        while (ptr)

        {

               if (k < ptr->key)

                       ptr = ptr->leftChild;

               else if (k>ptr->key)

                       ptr = ptr->rightChild;

               else

               {

                       e = ptr->element;

                       return true;

               }

        }

        return false;

}

 

template <class K, class E>

void BST<K, E>::Delete(Node<K, E> *&ptr, K &oldkey)

{

        //ptr를 루트로 하는 트리에서 oldkey를 키로 하는 노드를 지우시오

        Node<K, E> *tmpptr;

        Node<K, E> *tmpdaddyptr;

        if (ptr == 0)

               return; //그런 노드가 없으므로, 그냥 return

        if (oldkey < ptr->key) //좌측자식을 루트로 하는 트리에서 지우시오

               Delete(ptr->leftChild, oldkey);

        else if (oldkey > ptr->key) //우측자식을 루틀 하는 트리에서 지우시오

               Delete(ptr->rightChild, oldkey);

        else //ptr노드가 바로 지울 노드인 경우

        {

               if (!ptr->leftChild && !ptr->rightChild) //자식이 없다면

               {

                       delete ptr;

                       ptr = 0;

                       return;

               }

               else if (ptr->leftChild && !ptr->rightChild) //왼쪽자식만 있다면

               {

                       //그 자식을 ptr가 가리키게하고 현재 ptr가 가리키는 노드 지움

                       tmpptr = ptr;

                       ptr = ptr->leftChild;

                       delete tmpptr;

                       return;

               }

               else if (!ptr->leftChild && ptr->rightChild) //오른쪽자식만 있다면

               {

                       tmpptr = ptr;

                       ptr = ptr->rightChild;

                       delete tmpptr;

                       return;

               }

               else

               {

                       //두 자식 있음: 루트가 rc인 우측트리에서 '제일작은 노드' 찾자

                       Node<K, E> *rc = ptr->rightChild; //rc가 루트인 subtree

                       if (!rc->leftChild) //rc가 왼쪽자식이 없으면 rc가 그 노드!

                       {

                              ptr->key = rc->key;

                              ptr->element = rc->element;

                              ptr->rightChild = rc->rightChild;

                              delete rc;

                              return;

                       }

                       //rc의 왼쪽 자식이 있는 경우, rc의 왼쪽자식의 왼쪽자식의 식으로 왼쪽 자식을 끝까지 쫓아가, 가장 작은 키 갖는 노드를 찾는다

                       //그 노드의 key/element ptr노드로 옮기고 그 노드의 rightChild는 그 노드의 부모의 leftChild에 저장한 다음 그 노드를 지움

                       else

                       {

                              while (1)

                              {

                                      if (rc->leftChild)

                                      {

                                              tmpdaddyptr = rc;

                                              rc = rc->leftChild;

                                      }

                                      else

                                              break;

                              }

                              ptr->key = rc->key;

                              ptr->element = rc->element;

                              tmpdaddyptr->leftChild = rc->rightChild;

                              delete rc;

                              return;

                       }

               }

        }

}

 

template <class K, class E>

void BST<K, E>::Preorder(Node<K, E> *currentNode)

{

        if (currentNode)

        {

               Visit(currentNode);

               Preorder(currentNode->leftChild);

               Preorder(currentNode->rightChild);

        }

}

 

template <class K, class E>

void BST<K, E>::Inorder(Node<K, E> *currentNode)

{

        if (currentNode)

        {

               Inorder(currentNode->leftChild);

               Visit(currentNode);

               Inorder(currentNode->rightChild);

        }

}

 

template <class K, class E>

void BST<K, E>::Postorder(Node<K, E> *currentNode)

{

        if (currentNode)

        {

               Postorder(currentNode->leftChild);

               Postorder(currentNode->rightChild);

               Visit(currentNode);

        }

}

 

template <class K, class E>

void BST<K, E>::Levelorder()

{

        queue<Node<K, E>*> q;

        Node<K, E> *currentNode = root;

        while (currentNode)

        {

               Visit(currentNode);

               if (currentNode->leftChild)

                       q.push(currentNode->leftChild);

               if (currentNode->rightChild)

                       q.push(currentNode->rightChild);

               if (q.empty())

                       return;

               currentNode = q.front();

               q.pop();

        }

}

 

#endif

 

hw9.cpp

#include "bst.h"

 

int main(void)

{

        BST<string, double> tree;

        string command, str;

        double dval;

 

        while (cin >> command)

        {

               if (command == "insert")

               {

                       cin >> str >> dval;

                       tree.Insert(str, dval);

               }

               else if (command == "delete")

               {

                       cin >> str;

                       tree.Delete(str);

               }

               else if (command == "print")

               {

                       cout << endl << "Inorder traversal: ";

                       tree.Inorder();

                       cout << endl << "Postorder traversal: ";

                       tree.Postorder();

                       cout << endl;

               }

               else if (command == "find")

               {

                       cin >> str;

                       if (tree.Find(str, dval))

                              cout << "The value of " << str << " is " << dval << endl;

                       else

                              cout << "No such key: " << str << endl;

               }

               else

                       cout << "Invalid command: " << command << endl;

        }

        return 0;

}


개발환경:Visual Studio 2017


지적, 조언, 질문 환영입니다! 댓글 남겨주세요~


반응형

'학교 과제' 카테고리의 다른 글

c++로 작성한 최대 힙  (1) 2018.01.06
c++로 작성한 AVL 트리  (0) 2018.01.05
c++로 작성한 트리 순회  (0) 2018.01.02
c++로 작성한 링크드 리스트  (4) 2018.01.02
c++로 작성한 후위연산 계산기  (0) 2017.12.29