diff --git a/AbstractTree.h b/AbstractTree.h new file mode 100644 index 0000000..4694996 --- /dev/null +++ b/AbstractTree.h @@ -0,0 +1,32 @@ +#pragma once +#pragma once + #include "GroupContainer.h" + + // ����������� �����: ������ + class AbstractTree : public GroupContainer + { + public: + // ����������� + AbstractTree(MemoryManager & mem) : GroupContainer(mem) {} + + // ���������� + virtual ~AbstractTree() {} + + class Iterator : public Container::Iterator + { + public: + // ������� � ������������ �������. ���������� false ���� ������� ������� - ������ ��� end(). + virtual bool goToParent() = 0; + + // ������� � �������� ������� � child_index. ���������� false ���� �������� ������� � ����� ������� ���. + virtual bool goToChild(int child_index) = 0; + }; + + // ���������� �������� ��� �������� ������� � child_index �������, �� ������� + // ��������� ��������. � ������ ��������� ���������� ������� ���������� �������� 0, � ������ ������� 1. + virtual int insert(Iterator * iter, int child_index, void* elem, size_t size) = 0; + + // �������� �������, �� ������� ��������� ��������. ���� leaf_only==1 � ������� �� �������� ������, ���������� false + // !!! ����������: ����� remove ������� ������� ������ �� ����� �� ��������� + virtual bool remove(Iterator * iter, int leaf_only) = 0; + }; \ No newline at end of file diff --git a/Container.h b/Container.h new file mode 100644 index 0000000..baa2ae7 --- /dev/null +++ b/Container.h @@ -0,0 +1,77 @@ +#pragma once +#include +#include +#include +#include +#include +#include "MemoryManager.h" +#include "Mem.h" + +using namespace std; + + // ������� ����� ��� ���� ����������� ����������� +class Container +{ +protected: + MemoryManager& _memory; +public: + // ������� ����� ��� ����������, ������� ��������� ��������� + struct Error + { + char msg[256]; + Error(const char* err_msg) + { + strcpy(msg, err_msg); + } + }; + + class Iterator + { + public: + // ���������� ���� ��������� �� �������, �� ������� ��������� �������� � ������ ������. + // ������ ���������� ������ ������ + virtual void* getElement(size_t & size) = 0; + + // ���������� true, ���� ���� ��������� �������, ����� false. + virtual bool hasNext() = 0; + + // ������� � ���������� ��������. + virtual void goToNext() = 0; + + // �������� �� ��������� ���������� + virtual bool equals(Iterator * right) = 0; + }; + + Container(MemoryManager& mem) : _memory(mem) {} + + // ������� ���������� ��������, ������ ���������� ��������� � ����������. + virtual int size() = 0; + + // ������� ���������� ��������, ������ ������������ ����������� ���������� � ������. + virtual size_t max_bytes() = 0; //������� ��������� + + // ������� ���������� ��������� �� ��������, ����������� �� ������ ��������� + // � ���������� �������. ���� ������� �� ������, ������������ ������ ���������. + virtual Iterator* find(void* elem, size_t size) = 0; + + // �������� ���������, ���������������� ������� ���� ����������. + virtual Iterator* newIterator() = 0; + + // ������� ���������� ��������� �� ��������, ����������� �� ������ ������� + // ����������. ���� ��������� ������, ������������ ������� ���������. + virtual Iterator* begin() = 0; + + // ������� ���������� ��������� �� ��������, ����������� ������� �� ��������� + // ��������� ����������. ���� ��������� ������, ������������ ������� ���������. + virtual Iterator* end() = 0; + + // �������� �������� �� �������, �� ������� ��������� �������� iter. + // ����� �������� �������� ��������� �� ��������� �� ��������� �������. + virtual void remove(Iterator* iter) = 0; + + // �������� ���� ��������� �� ����������. + virtual void clear() = 0; + + // ���� ��������� ���� ���������� true, ����� false + virtual bool empty() = 0; +}; diff --git a/Container_contest.vcxproj b/Container_contest.vcxproj new file mode 100644 index 0000000..28a8558 --- /dev/null +++ b/Container_contest.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {2C08DEEC-A3EF-441E-A7F6-E989BD6B8872} + Containercontest + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996 + + + Console + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996 + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996 + + + Console + true + true + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4996 + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Container_contest.vcxproj.filters b/Container_contest.vcxproj.filters new file mode 100644 index 0000000..e051e53 --- /dev/null +++ b/Container_contest.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + + + Исходные файлы + + + Исходные файлы + + + + + Файлы ресурсов + + + \ No newline at end of file diff --git a/Container_contest.vcxproj.user b/Container_contest.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Container_contest.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/GroupContainer.h b/GroupContainer.h new file mode 100644 index 0000000..baf700b --- /dev/null +++ b/GroupContainer.h @@ -0,0 +1,9 @@ +#pragma once +#include "Container.h" + + // ������� ����� ��� ��������� ������ ����������� ����������� + class GroupContainer : public Container + { + public: + GroupContainer(MemoryManager & mem) : Container(mem) {} + }; \ No newline at end of file diff --git a/Mem.h b/Mem.h new file mode 100644 index 0000000..56a4109 --- /dev/null +++ b/Mem.h @@ -0,0 +1,19 @@ +#pragma once +#include "MemoryManager.h" + +// ���������� �������� ������, ���������� ::new � ::delete +class Mem : public MemoryManager +{ +public: + Mem(size_t sz) : MemoryManager(sz) {} + + void* allocMem(size_t sz) // ������ ��� ���������� ��� ������� + { + return new char[sz]; //��������� �������� ������ + } + + void freeMem(void* ptr) + { + delete[] ptr; + } +}; diff --git a/MemoryManager.h b/MemoryManager.h new file mode 100644 index 0000000..78539e4 --- /dev/null +++ b/MemoryManager.h @@ -0,0 +1,21 @@ +#pragma once +#include + +// ������� ����� ��������� ������ +class MemoryManager { +private: + size_t _size; +public: + MemoryManager(size_t sz) : _size(sz) {} + + size_t size() + { + return _size; + } + + virtual size_t maxBytes() { return -1; } + + virtual void* allocMem(size_t sz) = 0; + + virtual void freeMem(void* ptr) = 0; +}; diff --git a/Set.cpp b/Set.cpp new file mode 100644 index 0000000..e2f1e22 --- /dev/null +++ b/Set.cpp @@ -0,0 +1,309 @@ +#include "Set.h" +// ------------------------- ������ ������� ������ +int Set::compare(void* key1, size_t size1, void* key2, size_t size2) { + //���� ������ ������ ������ -1 ��� ��������� ������ 0 ���� ������ ������ ������ 1 + char k1[4], k2[4]; + for (int i = 0; i < 4; i++) { + k1[i] = ((char*)key1)[3 - i]; + k2[i] = ((char*)key2)[3 - i]; + } + if (size1 == size2) { + if (memcmp(k1, k2, size1) == 0) + return 0; + else if (memcmp(k1, k2, size1) < 0) + return -1; + else + return 1; + } + else if (size1 < size2) + return -1; + else + return 1; +} + +bool Set::search(Tree_node* root, void* elem_key, size_t size) +{ + if (root == nullptr) return false; + int temp = compare(root->key(), root->size(), elem_key, size); + if (temp == 0) + return true; + else if (temp == 1) + return search(root->left(), elem_key, size); + else + return search(root->right(), elem_key, size); +} + +Set::tree_pair Set::split(Tree_node* root, void* elem_key, size_t size) { + tree_pair ans; + if (root == nullptr) { + ans.first = nullptr; + ans.second = nullptr; + return ans; + } + int temp = compare(root->key(), root->size(), elem_key, size); + if (temp == -1) { + tree_pair splitted = split(root->right(), elem_key, size); + root->set_right(splitted.first); + if(splitted.first != nullptr) + splitted.first->set_parent(root); + if(splitted.second != nullptr) + splitted.second->set_parent(nullptr); + ans.first = root; ans.second = splitted.second; + } + else { + tree_pair splitted = split(root->left(), elem_key, size); + root->set_left(splitted.second); + if(splitted.second != nullptr) + splitted.second->set_parent(root); + if(splitted.first != nullptr) + splitted.first->set_parent(nullptr); + ans.first = splitted.first; ans.second = root; + } + return ans; +} + +Set::Tree_node* Set::merge(Tree_node* left, Tree_node* right) { + if (left == nullptr || right == nullptr) + return right == nullptr ? left : right; + if (left->priority() > right->priority()) { + + left->set_right(merge(left->right(), right)); + if (left->right() != nullptr) + left->right()->set_parent(left); + return left; + + } + else { + right->set_left(merge(left, right->left())); + if (right->left() != nullptr) + right->left()->set_parent(right); + return right; + + } +} +void Set::Tree_insert(Tree_node*& root, Tree_node *node_for_insert,void* key, size_t size) { + tree_pair splitted = split(root, key, size); + root = merge(merge(splitted.first, node_for_insert), splitted.second); +} + +void Set::print(Tree_node* root) { + if (root == nullptr) + return; + cout << "I go to the left" << endl; + print(root->left()); + int* a = static_cast(root->key()); + cout << "key = " << *a << " priority = " << root->priority() << endl; + cout << "I go to the right" << endl; + print(root->right()); +} + +// ************************ ����� ������� ������ + +// ---------------- ������ ������� ��������� + +Set::Tree_node* Set::SetIterator::next(Tree_node* current, bool first) { + Tree_node* temp_node = current; + if (temp_node->right() != nullptr && first == true) + return temp_node->right(); + else if (temp_node->parent() != nullptr) { + int temp; + char k1[4], k2[4]; + for (int i = 0; i < 4; i++) { + k1[i] = ((char*)temp_node->parent()->key())[3 - i]; + k2[i] = ((char*)temp_node->key())[3 - i]; + } + if (temp_node->parent()->size() == temp_node->size()) { + if (memcmp(k1, k2, temp_node->size()) == 0) + temp = 0; + else if (memcmp(k1, k2, temp_node->size()) < 0) + temp = -1; + else + temp = 1; + } + else if (temp_node->parent()->size() < temp_node->size()) + temp = -1; + else + temp = 1; + if (temp == 1) + return temp_node->parent(); + else { + return next(temp_node->parent(), false); + } + } + return nullptr; +} + +void* Set::SetIterator::getElement(size_t& size) { + if (_node == nullptr) + throw Container::Error("Get from empty iterator"); + size = _node->size(); + return _node->key(); +} +bool Set::SetIterator::hasNext() { + if (next(this->_node, true) == nullptr || this->_node == nullptr) + return false; + return true; +} +void Set::SetIterator::goToNext() { + if (this->hasNext() == false) + throw Container::Error("Going to not existing element"); + else + this->_node = this->next(_node, true); +} +bool Set::SetIterator::equals(Iterator* right) { + size_t s1, s2; void* k1, * k2; + k1 = this->getElement(s1); + k2 = right->getElement(s2); + return k1 == k2 && s1 == s2; +} +//********************* ����� ������� ��������� + +// -------------- ������ ������� ������ ��������� + +int Set::size() { + return this->c_size; +} +void Set::set_size(int size) { + this->c_size = size; +} +size_t Set::max_bytes() { + return this->_memory.maxBytes(); +} +int Set::insert(void* elem, size_t size) { + bool thereis = this->search(this->c_root, elem, size); + if (thereis) return -1; + void* temp_elem = this->_memory.allocMem(sizeof(Tree_node)); + Tree_node* node_for_insert = new (temp_elem) Tree_node(elem, size); + if (this->c_root == nullptr) { + this->c_root = node_for_insert; + this->c_size++; + return 0; + } + Tree_insert(this->c_root, node_for_insert, elem, size); + this->c_size++; + return 0; +} + +Set::Tree_node* Set::forFind(Tree_node* root, void* elem, size_t size) +{ + Tree_node* temp_node = root; + if (root == nullptr) return nullptr; + int temp = compare(root->key(), root->size(), elem, size); + if (temp == 0) + return temp_node; + else if (temp == 1) { + temp_node = temp_node->left(); + return forFind(temp_node, elem, size); + } + else { + temp_node = temp_node->right(); + return forFind(temp_node, elem, size); + } +} + +Set::SetIterator* Set::newIterator() { + void* forMem = this->_memory.allocMem(sizeof(SetIterator)); + SetIterator* forReturn = new (forMem) SetIterator; + return forReturn; +} + +Set::SetIterator* Set::find(void* elem, size_t size) { + Tree_node* temp_node = forFind(this->root(), elem, size); + SetIterator* Iter = newIterator(); + if (temp_node != nullptr) { + + Iter->setNode(temp_node); + return Iter; + } + else { + throw Container::Error("Haven't found given element"); + } +} + +Set::SetIterator* Set::begin() { + Tree_node* forSearch = this->root(); + while (forSearch->left() != nullptr) { + forSearch = forSearch->left(); + } + SetIterator* Iter = newIterator(); + Iter->setNode(forSearch); + return Iter; +} +Set::SetIterator* Set::end() { + Tree_node* forSearch = this->root(); + while (forSearch->right() != nullptr) { + forSearch = forSearch->right(); + } + SetIterator* Iter = newIterator(); + Iter->setNode(forSearch); + return Iter; +} + +void Set::erase(Tree_node*& root, void* elem, size_t size) { + int temp = compare(elem, size, root->key(), root->size()); + if (temp < 0) { + erase(root->c_left, elem, size); + if(root->c_left != nullptr) + root->c_left->set_parent(root); + } + else if (temp > 0) { + erase(root->c_right, elem, size); + if(root->c_right != nullptr) + root->c_right->set_parent(root); + } + else { + Tree_node* temp_node = root; + root = merge(root->c_left, root->c_right); + this->_memory.freeMem((void*)temp_node); + } +} + +void Set::remove(Set::Iterator* iter) { + //SetIterator* it = (SetIterator*)iter; + SetIterator* it = dynamic_cast(iter); + if (it == nullptr) { + throw Container::Error("Trying to remove not existing element"); + } + try { + it = find(it->node()->key(), it->node()->size()); + } + catch (Container::Error exception) { + if (exception.msg == "Haven't found given element") { + throw Container::Error("Trying to remove not existing element"); + } + } + this->c_size--; + erase(this->c_root, it->node()->key(), it->node()->size()); + if (it->hasNext()) { + ((SetIterator*)iter)->goToNext(); + } + else { + ((SetIterator*)iter)->setNode(this->c_begin); + } +} + +void Set::forClear(Tree_node* root) { + if (root == nullptr) return; + if(root->left() != nullptr) + forClear(root->left()); + if(root->right() != nullptr) + forClear(root->right()); + root->set_parent(nullptr); + root->set_left(nullptr); + root->set_right(nullptr); + root->set_key(nullptr); + this->_memory.freeMem((void*)root); + root = nullptr; +} +void Set::clear() { + forClear(this->root()); + this->~Set(); + return; +} +bool Set::empty() { + if (this->size() == 0) { + return true; + } + return false; +} +// ************************* ����� ������� ��������� \ No newline at end of file diff --git a/Set.h b/Set.h new file mode 100644 index 0000000..ae66f2b --- /dev/null +++ b/Set.h @@ -0,0 +1,105 @@ +#pragma once +#include "SetAbstract.h" +#include "AbstractTree.h" +class Set : + public AbstractSet +{ + class Tree_node + { + private: + Tree_node* c_parent; + void* c_key; size_t c_size; int c_priority = rand(); + public: + Tree_node* c_left, * c_right; + Tree_node(void* new_elem, size_t new_size) { + this->c_size = new_size; + this->c_key = new_elem; + this->c_left = nullptr; + this->c_right = nullptr; + this->c_parent = nullptr; + this->c_priority = rand(); + } + ~Tree_node() { + this->c_left = nullptr; + this->c_right = nullptr; + this->c_parent = nullptr; + this->c_priority = 0; + this->c_size = 0; + this->c_key = nullptr; + } + Tree_node* left() { return this->c_left; } + Tree_node* right() { return this->c_right; } + Tree_node* parent() { return this->c_parent; } + void* key() { return this->c_key; } + size_t size() { return this->c_size; } + int priority() { return this->c_priority; } + void set_key(void* key) { this->c_key = key; } + void set_left(Tree_node* left) { this->c_left = left; } + void set_right(Tree_node* right) { this->c_right = right; } + void set_parent(Tree_node* parent) { this->c_parent = parent; } + void set_elem(void* key, size_t size) { this->c_key = key; this->c_size = size; } + }; + struct tree_pair { Tree_node* first, * second; }; + + int compare(void* key1, size_t size1, void* key2, size_t size2); + bool search(Tree_node* root, void* key, size_t size); + tree_pair split(Tree_node* root, void* key, size_t size); // + Tree_node* merge(Tree_node* left, Tree_node* right); + void Tree_insert(Tree_node* &root, Tree_node* node_for_insert, void* key, size_t size); //������� ������� � ����������� ����, � ����� ������������� + + int c_size; Tree_node* c_begin, * c_end; +public: + Tree_node* c_root; + Set(MemoryManager& mem) : AbstractSet(mem) { + this->_memory = mem; + c_begin = nullptr; + c_end = nullptr; + c_root = nullptr; + c_size = 0; + } + ~Set() { + c_begin = nullptr; + c_end = nullptr; + c_root = nullptr; + c_size = 0; + } + int size(); + void set_size(int size); + size_t max_bytes() override; + + class SetIterator : public Container::Iterator + { + Tree_node* _node; + Tree_node* next(Tree_node* current, bool first); + + public: + SetIterator() { this->_node = nullptr; } + SetIterator(Tree_node* node) { this->_node = node; } + void setNode(Tree_node* node) { this->_node = node; } + Tree_node* node() { return this->_node; } + + void* getElement(size_t& size) override; + bool hasNext() override; + void goToNext() override; + bool equals(Iterator* right) override; + }; + Tree_node* root() { return this->c_root; } + void set_root(Tree_node* root) { this->c_root = root; } + Tree_node* forFind(Tree_node* root, void* elem, size_t size); + SetIterator* find(void* elem, size_t size) override; + SetIterator* newIterator() override; + SetIterator* begin() override; + SetIterator* end() override; + void erase(Tree_node* &root, void* elem, size_t size); + void remove(Iterator* iter) override; + void forClear(Tree_node* root); + void clear() override; + bool empty() override; + void print(Tree_node* root); + int insert(void* elem, size_t size) override; + + + +}; +/* +*/ diff --git a/SetAbstract.h b/SetAbstract.h new file mode 100644 index 0000000..cebf970 --- /dev/null +++ b/SetAbstract.h @@ -0,0 +1,16 @@ +#pragma once +#include "GroupContainer.h" + +// ����������� �����: ��������� +class AbstractSet : public GroupContainer +{ +public: + // ����������� + AbstractSet(MemoryManager& mem) : GroupContainer(mem) {} + + // ���������� + virtual ~AbstractSet() {} + + // ���������� �������� � ��������� � ��������������� �������, � ������������ � ������� ���������� ���������. � ������ ��������� ���������� ������� ���������� �������� 0, ���� ����� ������� ��� ���� � ���������� - 1, �� ���� ��������� ������� - 2. + virtual int insert(void* elem, size_t size) = 0; +}; diff --git a/Text.txt b/Text.txt new file mode 100644 index 0000000..0fabcac --- /dev/null +++ b/Text.txt @@ -0,0 +1,76 @@ +1 ������ �������� ����������� 1 ���������? +� ������������ �������� ������ �������� ������� ���������� ��������� +memcmp ����� ��������� �� ������ ������ �� � ��� ������ ������ -1 ��� 1 +������ �������� ��� ������� ��� �������� +���� ������ �������� ������ �������� ��� ���� � ��� ������ +������ ���������� � ����� ��� ������� �������� ���������� ������ + +TreeSet(MemMan &mem) : +AbstractSet(mem), +{ + void* add = mem.alloc(sizeof(Node)); + root = new (addr) Node(); +} +~TreeSet() +{} +{ + root.~Node(); +mem.freeMem(root); +} + +�������� ������� ������� ���������� �������� +��������� � ������� ��� ���������� ������ + +// ������ ����� ������ + if (v->size == size) { + if (memcmp(v->key_elem, elem_key, size) == 0) + return true; + else if (memcmp(v->key_elem, elem_key, size) > 0) //���� ������� �������� ������ + return search(v->left, elem_key, size); + else + return search(v->right, elem_key, size); //���� ������� �������� ������ + } + else if (v->size > size) + return search(v->left, elem_key,size); + else + return search(v->right, elem_key,size); + + ������ ����� ������ + if (root->size == size) { + if (memcmp(root->key_elem,elem_key,size) < 0) //������ ���� ������ ������ + { + tree_pair splitted = split(root->right, elem_key,size); + root->right = splitted.first; + ans.first = root; ans.second = splitted.second; + } + else + { + tree_pair splitted = split(root->left, elem_key,size); + root->left = splitted.second; + ans.first = splitted.first; ans.second = root; + } + } + else if (root->size < size) { + tree_pair splitted = split(root->right, elem_key, size); + root->right = splitted.first; + ans.first = root; ans.second = splitted.second; + } + else { + tree_pair splitted = split(root->left, elem_key, size); + root->left = splitted.second; + ans.first = splitted.first; ans.second = root; + } + + ������� ���������� � ������� ������ � ��� + + + int insert(AbstractTree::Iterator *it, int child_index, void *elem, size_t size) { + Tree::Iterator *iter = dynamic_cast(it); + + + + + + + + diff --git a/Tree.h b/Tree.h new file mode 100644 index 0000000..02768e8 --- /dev/null +++ b/Tree.h @@ -0,0 +1,268 @@ +#pragma once +#include "TreeAbstract.h" +#include + +class Tree : public AbstractTree { + +private: + int _size; + + class Vertex { + + private: + void* _element; + size_t _element_size; + Vertex* _parent; + Vertex* _left_brother, * _right_brother; + Vertex* _first_child; + + public: + Vertex(void* _element, size_t _size_element, Vertex* _parent) { + this->_element = _element; + this->_element_size = _size_element; + this->_parent = _parent; + this->_left_brother = this->_right_brother = NULL; + this->_first_child = NULL; + } + + void* element() { return this->_element; } + size_t element_size() { return this->_element_size; } + + Vertex* parent() { return _parent; } + + Vertex* first_child() { return _first_child; } + void set_first_child(Vertex* _first_child) { this->_first_child = _first_child; } + + Vertex* left_brother() { return _left_brother; } + Vertex* right_brother() { return _right_brother; } + void set_left_brother(Vertex* _left_brother) { this->_left_brother = _left_brother; } + void set_right_brother(Vertex* _right_brother) { this->_right_brother = _right_brother; } + + }; + + Vertex* _root; + + void removeDFS(Vertex* v, bool remove_v) { + Vertex* u = v->first_child(); + while (u != NULL) { + Vertex* nu = u->right_brother(); + removeDFS(u, 1); + u = nu; + } + v->set_first_child(NULL); + if (remove_v) { + change_size(-1); + free_mem(v); + } + } + +public: + Tree(MemoryManager& mem) : AbstractTree(mem) { + this->_memory = mem; + _root = new (alloc_mem(sizeof(Vertex))) Vertex(NULL, 0, NULL); + _size = 0; + } + + ~Tree() { + Tree::clear(); + } + + void* alloc_mem(size_t size) { + return _memory.allocMem(size); + } + + void free_mem(void* ptr) { + _memory.freeMem(ptr); + } + + class Iterator : public AbstractTree::Iterator { + + private: + Vertex* _vertex; + + Vertex* goNext(Vertex* s) { + Vertex* v = s; + if (v->first_child() != NULL) { + return v->first_child(); + } + while (v != NULL) { + if (v->right_brother() != NULL) { + return v->right_brother(); + } + v = v->parent(); + } + return NULL; + } + + public: + Iterator() { _vertex = NULL; } + + Iterator(Vertex* vertex) { this->_vertex = vertex; } + + Vertex* vertex() { return _vertex; } + void set_vertex(Vertex* _vertex) { this->_vertex = _vertex; } + + void* getElement(size_t& size) { + if (_vertex == NULL) { + throw Container::Error("Called getElement from empty Iterator"); + } + size = _vertex->element_size(); + return _vertex->element(); + } + + bool hasNext() { + if (_vertex == NULL) + return false; + if (goNext(_vertex) == NULL) + return false; + return true; + } + + void goToNext() { + if (!hasNext()) { + throw Container::Error("Wanted to go next, but it doesn't exist"); + } + _vertex = goNext(_vertex); + } + + bool equals(Container::Iterator* rgt) { + Tree::Iterator* right = dynamic_cast(rgt); + if (vertex() == NULL || right->vertex() == NULL) + return false; + return vertex() == right->vertex(); + // size_t sz1, sz2; + // void* v1 = getElement(sz1); + // void* v2 = right->getElement(sz2); + // return v1 == v2 && sz1 == sz2; + } + + bool goToParent() { + if (_vertex == NULL) + return false; + if (_vertex->parent() == NULL) + return false; + _vertex = _vertex->parent(); + return true; + } + + bool goToChild(int child_index) { + Vertex* child = _vertex->first_child(); + for (int i = 0; i < child_index; i++) { + if (child == NULL) + return false; + child = child->right_brother(); + } + if (child == NULL) + return false; + _vertex = child; + return true; + } + }; + + Vertex* root() { return _root; } + + int size() { return _size; } + + void change_size(int delta) { _size += delta; } + + size_t max_bytes() { return this->_memory.maxBytes(); } // TODO TESTING + + Tree::Iterator* find(void* elem, size_t size) { + Tree::Iterator* iterator = new (alloc_mem(sizeof(Iterator))) Iterator(_root); + while (iterator->hasNext()) { + iterator->goToNext(); + size_t nsize; + void* nelem = iterator->getElement(nsize); + if (elem == nelem && size == nsize) { + return iterator; + } + } + return newIterator(); + } + + Tree::Iterator* newIterator() { + return new (alloc_mem(sizeof(Iterator))) Iterator(); + } + + Tree::Iterator* begin() { + return new (alloc_mem(sizeof(Iterator))) Iterator(_root); + } + + Tree::Iterator* end() { + return newIterator(); + } + + void remove(Container::Iterator* it) { + Tree::Iterator* iter = dynamic_cast(it); + remove(iter, 1); + } + + void clear() { + Tree:Iterator* iterator = new Iterator(_root); + remove(iterator, 0); + _root = new (alloc_mem(sizeof(Vertex))) Vertex(NULL, 0, NULL); + _size = 0; + } + + bool empty() { + return this->size() ? false : true; + } + + int insert(AbstractTree::Iterator* it, int child_index, void* elem, size_t size) { + Tree::Iterator* iter = dynamic_cast(it); + if (iter->vertex() == NULL || child_index < 0) { + return 1; + } + Vertex* vertex = iter->vertex(); + Vertex* nvertex = new (alloc_mem(sizeof(Vertex))) Vertex(elem, size, vertex); + Vertex* first_child = vertex->first_child(); + if (child_index == 0) { + vertex->set_first_child(nvertex); + nvertex->set_right_brother(first_child); + if (first_child != NULL) + first_child->set_left_brother(nvertex); + } + else { + for (int i = 0; i < child_index - 1; i++) { + first_child = first_child->right_brother(); + if (first_child == NULL) { + return 1; + } + } + Vertex* right_brother = first_child->right_brother(); + first_child->set_right_brother(nvertex); + nvertex->set_left_brother(first_child); + nvertex->set_right_brother(right_brother); + if (right_brother != NULL) + right_brother->set_left_brother(nvertex); + } + change_size(1); + return 0; + } + + bool remove(AbstractTree::Iterator* it, int leaf_only) { + Tree::Iterator* iter = dynamic_cast(it); + Vertex* v = iter->vertex(); + if (leaf_only == 1 && v->first_child() != NULL) { + return false; + } + if (v->left_brother() != NULL) { + v->left_brother()->set_right_brother(v->right_brother()); + } + if (v->right_brother() != NULL) { + v->right_brother()->set_left_brother(v->left_brother()); + } + Vertex* p = v->parent(); + if (p != NULL && p->first_child() == v) { + p->set_first_child(v->right_brother()); + } + removeDFS(v, 0); + if (iter->hasNext()) + iter->goToNext(); + else + iter->set_vertex(NULL); + removeDFS(v, 1); + return true; + } + +}; \ No newline at end of file diff --git a/TreeAbstract.h b/TreeAbstract.h new file mode 100644 index 0000000..7c3c2c4 --- /dev/null +++ b/TreeAbstract.h @@ -0,0 +1,31 @@ +#pragma once +#include "GroupContainer.h" + +// ����������� �����: ������ +class AbstractTree : public GroupContainer +{ +public: + // ����������� + AbstractTree(MemoryManager& mem) : GroupContainer(mem) {} + + // ���������� + virtual ~AbstractTree() {} + + class Iterator : public Container::Iterator + { + public: + // ������� � ������������ �������. ���������� false ���� ������� ������� - ������ ��� end(). + virtual bool goToParent() = 0; + + // ������� � �������� ������� � child_index. ���������� false ���� �������� ������� � ����� ������� ���. + virtual bool goToChild(int child_index) = 0; + }; + + // ���������� �������� ��� �������� ������� � child_index �������, �� ������� + // ��������� ��������. � ������ ��������� ���������� ������� ���������� �������� 0, � ������ ������� 1. + virtual int insert(Iterator* iter, int child_index, void* elem, size_t size) = 0; + + // �������� �������, �� ������� ��������� ��������. ���� leaf_only==1 � ������� �� �������� ������, ���������� false + // !!! ����������: ����� remove ������� ������� ������ �� ����� �� ��������� + virtual bool remove(Iterator* iter, int leaf_only) = 0; +}; \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..4b0b551 --- /dev/null +++ b/main.cpp @@ -0,0 +1,118 @@ +#include +#include +#include "Set.h" +#include +using namespace std; + +int test_passed(string test_name) { + cout << test_name << " successfully passed :)" << endl; + return 1; +} +int test_failed(string test_name) { + cout << test_name << " failed :(" << endl; + return 0; +} + +void first_test_insert() { + Mem mm(1000); + Set s(mm); + int elem6 = 8, elem3 = 7, elem5 = 3, elem9 = 33, elem0 = 4; + size_t size; + + s.insert(&elem6, sizeof(elem6)); + s.insert(&elem3, sizeof(elem3)); + s.insert(&elem5, sizeof(elem5)); + s.insert(&elem9, sizeof(elem9)); + s.insert(&elem0, sizeof(elem0)); + s.print(s.root()); + Set::SetIterator*it = s.end(); + int* b = static_cast(it->getElement(size)); + cout << "end = " << *b << " size = " << size << endl; + + try { + it->goToNext(); + b = static_cast(it->getElement(size)); + cout << "end = " << *b << " size = " << size << endl; + } + catch (Container::Error exception) { + cerr << exception.msg << endl; + } + it = s.begin(); + int* a = static_cast(it->getElement(size)); + cout << "begin = " << *a <<" size = " << size << endl; + it->goToNext(); + int* c = static_cast(it->getElement(size)); + cout << "next = " << *c << " size = " << size << endl; + + cout << "Using iterator" << endl; + for (it = s.begin(); it->hasNext(); it->goToNext()) { + int* d = static_cast(it->getElement(size)); + cout << "elem = " << *d << " size = " << size << endl; + } + int* d = static_cast(it->getElement(size)); + cout << "elem = " << *d << " size = " << size << endl; + cout << endl << endl; + it = s.find(&elem3, sizeof(elem3)); + d = static_cast(it->getElement(size)); + cout << "found elem = " << *d << " size = " << size << endl; + cout << "set size = " << s.size() << endl; + cout << "before clearing" << endl; + s.print(s.root()); + cout << "size = " << s.size() << endl; + //s.clear(); + cout << "after erasing" << endl; + try { + it = s.find(&elem3, sizeof(elem3)); + s.remove(it); + s.print(s.root()); + cout << "I have removed" << endl; + cout << "size = " << s.size() << endl; + } + catch (Container::Error exception) { + cerr << exception.msg << endl; + } + try { + it = s.find(&elem3, sizeof(elem3)); + d = static_cast(it->getElement(size)); + cout << "found elem = " << *d << " size = " << size << endl; + } + catch (Container::Error exception) { + it = nullptr; + cerr << exception.msg << endl; + } + try { + s.remove(it); + } + catch (Container::Error exception) { + cerr << exception.msg << endl; + } + s.clear(); + cout << "after clearing" << endl; + s.print(s.root()); +} + +void random_insert() { + //srand(time(0)); + Mem mm(5000); + Set s(mm); + int test_massive[1000], mas2[6] = { 6,3,5,3,9,0 }; + for (int i = 0; i < 1000; i++) { + test_massive[i] = rand(); + } + for (int i = 0; i < 1000; i++) { + cout << i + 1 << " = " << &test_massive[i] << endl; + } + cout << "after adding to set: " << endl << endl; + for (int i = 0; i < 1000; i++) { + s.insert(&test_massive[i], sizeof(int)); + } + s.print(s.root()); +} + + +int main() { + first_test_insert(); + //cout << "test 2:" << endl << endl; + //random_insert(); + return 0; +} \ No newline at end of file