mirror of
https://github.com/tiennm99/HCMUT.git
synced 2026-10-14 16:17:22 +00:00
Update Assignment
This commit is contained in:
1 parent
edd9b9a1f6
commit
a4393f4d3b
9 files changed
+983
No files matched your search
@@ -0,0 +1,273 @@
|
||||
//use "balance" varialbe as "height"
|
||||
|
||||
#include "TreeSet.h"
|
||||
|
||||
static bool isSuccess;
|
||||
|
||||
TreeSet::TreeSet()
|
||||
{
|
||||
root = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
TreeSet::~TreeSet()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void TreeSet::clearRec(AVLNode *root)
|
||||
{
|
||||
if (root != nullptr) {
|
||||
clearRec(root->left);
|
||||
clearRec(root->right);
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
|
||||
void TreeSet::clear()
|
||||
{
|
||||
clearRec(root);
|
||||
root = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
int TreeSet::add(int val)
|
||||
{
|
||||
isSuccess = false;
|
||||
root = recursiveAdd(root, val);
|
||||
if (isSuccess) {
|
||||
++count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TreeSet::contains(int val)
|
||||
{
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key > val)
|
||||
temp = temp->left;
|
||||
else if (temp->key < val)
|
||||
temp = temp->right;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TreeSet::copy(const TreeSet &set)
|
||||
{
|
||||
clear();
|
||||
root = recursiveCopy(set.root);
|
||||
count = set.count;
|
||||
}
|
||||
|
||||
int TreeSet::first()
|
||||
{
|
||||
if (root == nullptr) {
|
||||
throw "NoSuchElementException";
|
||||
}
|
||||
AVLNode *temp = root;
|
||||
while (temp->left != nullptr)
|
||||
temp = temp->left;
|
||||
return temp->key;
|
||||
}
|
||||
|
||||
int TreeSet::last()
|
||||
{
|
||||
if (root == nullptr) {
|
||||
throw "NoSuchElementException";
|
||||
}
|
||||
AVLNode *temp = root;
|
||||
while (temp->right != nullptr)
|
||||
temp = temp->right;
|
||||
return temp->key;
|
||||
}
|
||||
|
||||
int TreeSet::higher(int val)
|
||||
{
|
||||
if (root == nullptr)
|
||||
return -1;
|
||||
int higher = last();
|
||||
if (val >= higher)
|
||||
return -1;
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key > val) {
|
||||
if (temp->key < higher)
|
||||
higher = temp->key;
|
||||
temp = temp->left;
|
||||
} else {
|
||||
temp = temp->right;
|
||||
}
|
||||
}
|
||||
return higher;
|
||||
}
|
||||
|
||||
int TreeSet::lower(int val)
|
||||
{
|
||||
if (root == nullptr)
|
||||
return -1;
|
||||
int lower = first();
|
||||
if (val <= lower)
|
||||
return -1;
|
||||
AVLNode *temp = root;
|
||||
while (temp != nullptr) {
|
||||
if (temp->key < val) {
|
||||
if (temp->key > lower)
|
||||
lower = temp->key;
|
||||
temp = temp->right;
|
||||
} else {
|
||||
temp = temp->left;
|
||||
}
|
||||
}
|
||||
return lower;
|
||||
}
|
||||
|
||||
int TreeSet::remove(int val)
|
||||
{
|
||||
isSuccess = false;
|
||||
root = recursiveRemove(root, val);
|
||||
if (isSuccess) {
|
||||
--count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TreeSet *TreeSet::subSet(int fromVal, int toVal)
|
||||
{
|
||||
TreeSet *subSet = new TreeSet;
|
||||
recursiveSubSet(subSet, root, fromVal, toVal);
|
||||
return subSet;
|
||||
}
|
||||
|
||||
int TreeSet::size()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
int TreeSet::getHeight(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return 0;
|
||||
return node->balance;
|
||||
}
|
||||
|
||||
void TreeSet::setHeight(AVLNode *&node)
|
||||
{
|
||||
node->balance = max(getHeight(node->left), getHeight(node->right)) + 1;
|
||||
}
|
||||
|
||||
int TreeSet::getBalance(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return 0;
|
||||
return getHeight(node->left) - getHeight(node->right);
|
||||
}
|
||||
|
||||
void TreeSet::recursiveSubSet(TreeSet *&subSet, AVLNode *node, int fromVal, int toVal)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return;
|
||||
if (node->key < fromVal) {
|
||||
recursiveSubSet(subSet, node->right, fromVal, toVal);
|
||||
} else if (node->key < toVal) {
|
||||
subSet->add(node->key);
|
||||
recursiveSubSet(subSet, node->left, fromVal, toVal);
|
||||
recursiveSubSet(subSet, node->right, fromVal, toVal);
|
||||
} else {
|
||||
recursiveSubSet(subSet, node->left, fromVal, toVal);
|
||||
}
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveAdd(AVLNode *&node, int val)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
isSuccess = true;
|
||||
return new AVLNode(val, 1);
|
||||
}
|
||||
if (node->key == val)
|
||||
return node;
|
||||
if (node->key > val)
|
||||
node->left = recursiveAdd(node->left, val);
|
||||
else
|
||||
node->right = recursiveAdd(node->right, val);
|
||||
setHeight(node);
|
||||
return rebalance(node);
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveRemove(AVLNode *&node, int val)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return node;
|
||||
if (node->key > val) {
|
||||
node->left = recursiveRemove(node->left, val);
|
||||
} else if (node->key < val) {
|
||||
node->right = recursiveRemove(node->right, val);
|
||||
} else {
|
||||
if (node->left == nullptr) {
|
||||
AVLNode *temp = node->right;
|
||||
delete node;
|
||||
isSuccess = true;
|
||||
return temp;
|
||||
}
|
||||
AVLNode *delNode = node->left;
|
||||
while (delNode->right != nullptr)
|
||||
delNode = delNode->right;
|
||||
node->key = delNode->key;
|
||||
node->left = recursiveRemove(node->left, node->key);
|
||||
}
|
||||
return rebalance(node);
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::recursiveCopy(AVLNode *node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return node;
|
||||
AVLNode *temp = new AVLNode(node->key, node->balance);
|
||||
temp->left = recursiveCopy(node->left);
|
||||
temp->right = recursiveCopy(node->right);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rotateLeft(AVLNode *&node)
|
||||
{
|
||||
AVLNode *temp = node->right;
|
||||
AVLNode *tmp = temp->left;
|
||||
node->right = tmp;
|
||||
temp->left = node;
|
||||
setHeight(node);
|
||||
setHeight(temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rotateRight(AVLNode *&node)
|
||||
{
|
||||
AVLNode *temp = node->left;
|
||||
AVLNode *tmp = temp->right;
|
||||
node->left = tmp;
|
||||
temp->right = node;
|
||||
setHeight(node);
|
||||
setHeight(temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
AVLNode *TreeSet::rebalance(AVLNode *&node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
return nullptr;
|
||||
int balance = getBalance(node);
|
||||
if (balance > 1) {
|
||||
if (getBalance(node->left) < -1)
|
||||
node->left = rotateLeft(node->left);
|
||||
node = rotateRight(node);
|
||||
} else if (balance < -1) {
|
||||
if (getBalance(node->right) > 1)
|
||||
node->right = rotateRight(node->right);
|
||||
node = rotateLeft(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
Reference in new issue
Block a user