Files
School/Anul 1/Semestrul 2/Data structures/Lab 5/SortedBag.cpp
T
2024-08-31 12:07:21 +03:00

239 lines
4.7 KiB
C++

#include "SortedBag.h"
#include "SortedBagIterator.h"
#include <exception>
SortedBag::SortedBag(Relation r) {
//TODO - Implementation
this->relation = r;
this->root = nullptr;
this->length = 0;
}
void SortedBag::add(TComp e) {
//Best case: O(1) Worst case: O(n) Average case: O(log n)
BSTNode* newNode = new BSTNode;
newNode->elem = e;
newNode->left = nullptr;
newNode->right = nullptr;
newNode->parent = nullptr;
newNode->count = 1;
if (this->root == nullptr) {
this->root = newNode;
this->length++;
return;
}
BSTNode* current = this->root;
while (current != nullptr) {
if (current->elem == e) {
current->count++;
this->length++;
return;
}
if (this->relation(e, current->elem)) {
if (current->left == nullptr) {
current->left = newNode;
newNode->parent = current;
this->length++;
return;
}
else {
current = current->left;
}
}
else {
if (current->right == nullptr) {
current->right = newNode;
newNode->parent = current;
this->length++;
return;
}
else {
current = current->right;
}
}
}
}
bool SortedBag::remove(TComp e) {
//Best case: O(1) Worst case: O(n) Average case: O(log n)
BSTNode* current = this->root;
while (current != nullptr) {
if(current->elem==e){
if(current->count>1){
current->count--;
this->length--;
return true;
}
else{
if(current->left==nullptr && current->right==nullptr){
if(current->parent==nullptr){
this->root=nullptr;
this->length--;
return true;
}
else{
if(current->parent->left==current){
current->parent->left=nullptr;
this->length--;
return true;
}
else{
current->parent->right=nullptr;
this->length--;
return true;
}
}
}
else{
if(current->left==nullptr){
if(current->parent==nullptr){
this->root=current->right;
this->root->parent=nullptr;
this->length--;
return true;
}
else{
if(current->parent->left==current){
current->parent->left=current->right;
this->length--;
return true;
}
else{
current->parent->right=current->right;
this->length--;
return true;
}
}
}
else{
if(current->right==nullptr){
if(current->parent==nullptr){
this->root=current->left;
this->root->parent=nullptr;
this->length--;
return true;
}
else{
if(current->parent->left==current){
current->parent->left=current->left;
this->length--;
return true;
}
else{
current->parent->right=current->left;
this->length--;
return true;
}
}
}
else{
BSTNode* current2=current->right;
while(current2->left!=nullptr){
current2=current2->left;
}
current->elem=current2->elem;
current->count=current2->count;
if(current2->parent->left==current2){
current2->parent->left=current2->right;
this->length--;
return true;
}
else{
current2->parent->right=current2->right;
this->length--;
return true;
}
}
}
}
}
}
else{
if(this->relation(e,current->elem)){
current=current->left;
}
else{
current=current->right;
}
}
}
return false;
}
bool SortedBag::search(TComp elem) const {
// Best case: O(1) Worst case: O(n) Average case: O(log n)
BSTNode* current = this->root;
while (current != nullptr) {
if (current->elem == elem) {
return true;
}
if (this->relation(elem, current->elem)) {
current = current->left;
}
else {
current = current->right;
}
}
return false;
}
int SortedBag::nrOccurrences(TComp elem) const {
// Best case: O(1) Worst case: O(n) Average case: O(log n)
BSTNode* current = this->root;
while (current != nullptr) {
if (current->elem == elem) {
return current->count;
}
if (this->relation(elem, current->elem)) {
current = current->left;
}
else {
current = current->right;
}
}
return 0;
}
int SortedBag::size() const {
//O(1)
return this->length;
}
bool SortedBag::isEmpty() const {
//O(1)
return (this->length == 0);
}
SortedBagIterator SortedBag::iterator() const {
return SortedBagIterator(*this);
}
SortedBag::~SortedBag() {
//O(n)
delete this->root;
}
int SortedBag::elementsWithThisFrequency(int frequency) const {
// O(n)
if(frequency<=0){
throw std::exception();
}
return reccuriveCount(this->root,frequency);
}
int SortedBag::reccuriveCount(BSTNode* node, int frequency) const {
if(node==nullptr){
return 0;
}
return reccuriveCount(node->left,frequency)+reccuriveCount(node->right, frequency) + (this->nrOccurrences(node->elem)==frequency);
}