규태
#ifndef __BinarySearchTree__GBinarySearchTree__
#define __BinarySearchTree__GBinarySearchTree__
#include <iostream>
#include <string>
#include <stack>
#include <queue>
template <typename E>
class GBinarySearchTree {
public:
typedef std::string Key;
protected:
class Node {
public:
Key key;
E elem;
Node *parent;
Node *left_child;
Node *right_child;
Node(): key(), elem(), parent(NULL), left_child(NULL), right_child(NULL) {}
Node(const Key& _key, const E& _elem)
: key(_key), elem(_elem), parent(NULL), left_child(NULL), right_child(NULL) {}
};
public:
GBinarySearchTree();
int getSize() const { return size; }
bool isEmpty() const { return size == 0; }
E& get(const Key& _key);
void insert(const Key& _key, const E& _elem);
void erase(const Key& _key);
void printKeysWithOption(int opt);
private:
Node* getRoot() { return v_root->right_child; }
Node* _get(const Key& _key);
bool _isExternal(Node* p) { return (p->left_child == NULL && p->right_child == NULL); }
void _printKeysWithPreOrder();
void _printKeysWithInOrder();
void _printKeysWithPostOrder();
void _printKeysWithLevelOrder();
private:
Node *v_root;
int size;
};
template <typename E>
GBinarySearchTree<E>::GBinarySearchTree() {
v_root = new Node();
size = 0;
}
template <typename E>
E& GBinarySearchTree<E>::get(const Key& _key) {
Node *target = _get(_key);
return target->elem;
}
template <typename E>
typename GBinarySearchTree<E>::Node* GBinarySearchTree<E>::_get(const Key& _key) {
Node* p = getRoot();
while (p != NULL) {
if (_key < p->key)
p = p->left_child;
else if(_key > p->key)
p = p->right_child;
else
break;
}
return p;
}
template <typename E>
void GBinarySearchTree<E>::insert(const Key& _key, const E& _elem) {
Node *node = new Node(_key, _elem);
if (size == 0) {
v_root->right_child = node;
node->parent = v_root;
size++;
return;
}
Node *p = getRoot();
while (p != NULL) {
if (_key < p->key) {
if (p->left_child != NULL) {
p = p->left_child;
}
else {
p->left_child = node;
node->parent = p;
}
}
else if (_key > p->key) {
if (p->right_child != NULL) {
p = p->right_child;
}
else {
p->right_child = node;
node->parent = p;
}
}
else {
p->elem = _elem;
return;
}
}
size++;
}
template <typename E>
void GBinarySearchTree<E>::erase(const Key& _key) {
Node *target = _get(_key);
if (target == NULL)
return;
if (_isExternal(target)) {
Node *t_parent = target->parent;
if (t_parent->left_child == target)
t_parent->left_child = NULL;
else
t_parent->right_child = NULL;
delete target;
}
if (target->left_child != NULL) {
Node *p = target->left_child;
while (p->right_child != NULL)
p = p->right_child;
target->key = p->key;
target->elem = p->elem;
if (p->parent == target) {
if (p->left_child != NULL)
target->left_child = p->left_child;
else
target->left_child = NULL;
}
else {
if (p->left_child != NULL)
p->parent->right_child = p->left_child;
else
p->parent->right_child = NULL;
}
delete p;
}
else {
Node *p = target->right_child;
while (p->left_child != NULL)
p = p->left_child;
target->key = p->key;
target->elem = p->elem;
if (p->parent == target) {
if (p->right_child != NULL)
target->right_child = p->right_child;
else
target->right_child = NULL;
}
else {
if (p->right_child != NULL)
p->parent->left_child = p->right_child;
else
p->parent->left_child = NULL;
}
delete p;
}
}
template <typename E>
void GBinarySearchTree<E>::printKeysWithOption(int opt) {
switch (opt) {
case 0:
_printKeysWithPreOrder();
break;
case 3:
_printKeysWithLevelOrder();
break;
default:
break;
}
}
template <typename E>
void GBinarySearchTree<E>::_printKeysWithPreOrder() {
std::stack<Node*> st;
Node *p = getRoot();
if (p == NULL)
return;
st.push(p);
while (!st.empty()) {
p = st.top();
std::cout << p->key << ", ";
st.pop();
if (p->right_child != NULL)
st.push(p->right_child);
if (p->left_child != NULL)
st.push(p->left_child);
}
std::cout << std::endl;
}
template <typename E>
void GBinarySearchTree<E>::_printKeysWithPostOrder() {
}
template <typename E>
void GBinarySearchTree<E>::_printKeysWithLevelOrder() {
std::queue<Node*> q;
Node *p = getRoot();
if(p == NULL)
return;
q.push(p);
Node *pp = v_root;
while (!q.empty()) {
p = q.front();
std::cout << p->key << " ";
q.pop();
if (pp->right_child == p) {
std::cout << std::endl;
pp = p;
}
if (p->left_child != NULL)
q.push(p->left_child);
if (p->right_child != NULL)
q.push(p->right_child);
}
std::cout << std::endl;
}
#endif /* defined(__BinarySearchTree__GBinarySearchTree__) */