Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set 기능 구현 #59

Merged
merged 12 commits into from
Dec 12, 2023
2 changes: 2 additions & 0 deletions header/adaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ class Adaptor {
virtual int size() = 0;
virtual int find(T value) = 0;
virtual int insert(T value) = 0;
virtual int erase(const T& key) = 0;
virtual int rank(T target) = 0;
};
#endif
7 changes: 5 additions & 2 deletions header/avl_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,22 @@

/* AVL Tree Class */
template <typename T>
class AVLTree : public virtual BinarySearchTree<T>, public virtual Adaptor<T> {
class AVLTree : public virtual Adaptor<T>, public virtual BinarySearchTree<T> {
public:
AVLTree();
NodePtr<T> recursiveInsert(NodePtr<T> current_node, T item) override;
int insert(T item) override;
int getBalanceFactor(NodePtr<T> current_node);
int erase(const T& key);
int erase(const T& key) override;
void eraseNode(NodePtr<T>& root, const T& key);
void transplant(NodePtr<T>& x);
NodePtr<T> findSuccessor(const NodePtr<T>& node);
int find(int item) override {
return BinarySearchTree<T>::findDepthByValue(item);
};
int rank(T target) override {
return BinarySearchTree<T>::rank(this->getRoot(), target);
}
T minimum(T item) override { return BinarySearchTree<T>::minimum(item); }
T maximum(T item) override { return BinarySearchTree<T>::maximum(item); }
int size() override { return BinarySearchTree<T>::getSize(); }
Expand Down
2 changes: 2 additions & 0 deletions header/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class Set {
bool empty();
T maximum(T value);
T minimum(T value);
int erase(T value);
int rank(T value);

private:
Adaptor<T>* adaptor_;
Expand Down
69 changes: 28 additions & 41 deletions source/avl_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,69 +156,69 @@ void AVLTree<T>::balancing(NodePtr<T>& current_node, T item) {
/* erase: 노드 삭제 후 depth 반환하기 */
template <typename T>
int AVLTree<T>::erase(const T& key) {
cout << "erase in AVLTree called\n";
NodePtr<T> node = this->IsKey(key);
if (node != nullptr) {
int depth = this->findDepthByValue(key);
eraseNode(this->root_, key);
this->size_ = this->size_ - 1;
cout << "return depth\n";
return depth;
} else {
cout << "return depth 0\n";
return 0;
}
}

/* eraseNode: 실질적인 노드 삭제 수행 */
template <typename T>
void AVLTree<T>::eraseNode(NodePtr<T>& root, const T& key) {
cout << "eraseNode in AVLTree called \n";
if (root == nullptr) {
return; // 비어 있다면 넘기기
}

if (key < root->key) {
if (key < root->key && root->left != nullptr) {
eraseNode(root->left, key);
} else if (key > root->key) {
} else if (key > root->key && root->right != nullptr) {
eraseNode(root->right, key);
} else {
if (root->left == nullptr) {
transplant(root->right);
} else if (root->right == nullptr) {
transplant(root->left);
} else {
NodePtr<T> successor = findSuccessor(root->right);
root->key = successor->key;
eraseNode(root->right, successor->key);
}

} else if (root->key == key) {
transplant(root);
}
if (root != nullptr) {
root->height =
1 + max(this->getHeight(root->left), this->getHeight(root->right));
if (getBalanceFactor(root) == 2 && getBalanceFactor(root->left) == 1) {
root = rotateRight(root);
} else if (getBalanceFactor(root) == 2 &&
getBalanceFactor(root->left) == -1) {
root->left = rotateLeft(root->left);
root = rotateRight(root);
} else if (getBalanceFactor(root) == 2 &&
getBalanceFactor(root->left) == 0) {
root = rotateRight(root);
} else if (getBalanceFactor(root) == -2 &&
getBalanceFactor(root->right) == -1) {
root = rotateLeft(root);
} else if (getBalanceFactor(root) == -2 &&
getBalanceFactor(root->right) == 1) {
root->right = rotateRight(root->right);
root = rotateLeft(root);
} else if (getBalanceFactor(root) == -2 &&
getBalanceFactor(root->right) == 0) {
root = rotateRight(root);
}
}
}

/* Transplant: 자식 노드 이식 함수 */
template <typename T>
void AVLTree<T>::transplant(NodePtr<T>& x) {
NodePtr<T> y = x; // 노드 삭제를 위해 y 사용

if (x->left == nullptr) {
x = x->right;
} else if (x->right == nullptr) {
x = x->left;
} else {
NodePtr<T> z = x->right; // z : 삭제할 x의 다음으로 가장 작은 수
NodePtr<T> pZ = x; // p[z] : z의 부모 노드
NodePtr<T> z = x->right; // z : 삭제할 x보다 큰 수들 중 가장 작은 수
NodePtr<T> pZ = x;

/* 오른쪽 자식중 가장 작은 값 찾기*/
while (z->left != nullptr) {
pZ = z;
z = z->left;
}

x->key = z->key; // successor과 key값 교환

/* 오른쪽 자식이 가장 작다면 */
if (pZ == x) {
pZ->right = z->right; // z의 오른쪽 자식 붙여주기
Expand All @@ -228,18 +228,5 @@ void AVLTree<T>::transplant(NodePtr<T>& x) {

// 이식 후 높이 업데이트
pZ->height = 1 + max(this->getHeight(pZ->left), this->getHeight(pZ->right));
x = pZ;

delete y; // 메모리 해제
}
}

/* findSuccessor: 후임자 찾기 역할 */
template <typename T>
NodePtr<T> AVLTree<T>::findSuccessor(const NodePtr<T>& node) {
NodePtr<T> current = node;
while (current->left != nullptr) {
current = current->left;
}
return current;
}
7 changes: 1 addition & 6 deletions source/bst_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ T BinarySearchTree<T>::minimum(T item) {
while (x->left != nullptr) {
x = x->left;
}
cout << x->key << " " << findDepthByValue(x->key) << "\n";
return x->key; // 최솟값 출력 뿐만 아니라 값을 리턴하도록 수정
return x->key;
}

/* find max */
Expand All @@ -105,7 +104,6 @@ T BinarySearchTree<T>::maximum(T item) {
while (x->right != nullptr) {
x = x->right;
}
cout << x->key << " " << findDepthByValue(x->key) << "\n";
return x->key;
}

Expand Down Expand Up @@ -173,8 +171,6 @@ int BinarySearchTree<T>::countNodesSmallerThan(NodePtr<T> root, T target) {

template <typename T>
int BinarySearchTree<T>::rank(NodePtr<T> root, T target) {
// cout << findDepthByValue(target) << " "
// << countNodesSmallerThan(root, target) + 1 << '\n';
return countNodesSmallerThan(root, target) + 1;
}

Expand All @@ -184,7 +180,6 @@ int BinarySearchTree<T>::rank(NodePtr<T> root, T target) {
/* erase: 노드 삭제 후 depth 반환하기 */
template <typename T>
int BinarySearchTree<T>::erase(const T& key) {
cout << "erase in BSTTree called \n";
NodePtr<T> node = IsKey(key);
if (node != nullptr) {
int depth = this->findDepthByValue(key);
Expand Down
71 changes: 43 additions & 28 deletions source/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,47 @@
using namespace std;

int main() {
Adaptor<int>* adaptor = new AVLTree<int>;
Set<int> set(adaptor);
set.insert(1);
set.insert(2);
set.insert(3);
set.insert(4);
set.find(4);
set.size();
set.empty();
set.maximum(2);
set.minimum(2);
set.size();

/* Adaptor insert
Adaptor<int>* ad = new AVLTree<int>;
ad->insert(1);
ad->insert(2);
ad->insert(3);
ad->insert(4);
cout << ad->find(1) << endl;
cout << ad->find(4) << endl;
cout << ad->empty() << endl;
cout << ad->size() << endl;
*/
/*AVLTree<int> avl;
Node<int>* root = nullptr;
root = avl.Insert(root, 42);
cout << root->key << endl;*/
int T;
cin >> T;
while (T--) {
int Q;
cin >> Q;
Adaptor<int>* adaptor = new AVLTree<int>;
Set<int> set(adaptor);
string s;
int n;
for (int i = 0; i < Q; i++) {
cin >> s;
if (s == "insert") {
cin >> n;
set.insert(n);
}
if (s == "find") {
cin >> n;
set.find(n);
}
if (s == "minimum") {
cin >> n;
set.minimum(n);
}
if (s == "maximum") {
cin >> n;
set.maximum(n);
}
if (s == "empty") {
set.empty();
}
if (s == "size") {
set.size();
}
if (s == "rank") {
cin >> n;
set.rank(n);
}
if (s == "erase") {
cin >> n;
set.erase(n);
}
}
}
}
24 changes: 22 additions & 2 deletions source/set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,30 @@ bool Set<T>::empty() {

template <typename T>
T Set<T>::maximum(T value) {
adaptor_->maximum(value) << '\n';
T maximumValue = adaptor_->maximum(value);
cout << maximumValue << " " << adaptor_->find(maximumValue) << "\n";
}

template <typename T>
T Set<T>::minimum(T value) {
adaptor_->minimum(value) << '\n';
T minimumValue = adaptor_->minimum(value);
cout << minimumValue << " " << adaptor_->find(minimumValue) << "\n";
}

template <typename T>
int Set<T>::erase(T value) {
int result = adaptor_->erase(value);
cout << result << "\n";
return result;
}

template <typename T>
int Set<T>::rank(T value) {
int depth = adaptor_->find(value);
if (depth == 0) {
cout << depth << "\n";
return depth;
}
cout << depth << " " << adaptor_->rank(value) << "\n";
return adaptor_->rank(value);
}
1 change: 0 additions & 1 deletion test/bst_tree_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ BinaryTreeTestFixture::~BinaryTreeTestFixture() {}
/* SetUp */
void BinaryTreeTestFixture::SetUp() {
int items[] = {1, 6, 5, 10, 7, 14, 21};
NodePtr<int> root = nullptr;
for (const int item : items) {
bst_.insert(item);
}
Expand Down
Loading