Skip to content

Commit

Permalink
YES 3 base
Browse files Browse the repository at this point in the history
  • Loading branch information
Andeo1812 committed May 17, 2022
1 parent f7a8e03 commit 985493b
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

all: clear build launch

TARGET_DZ = 4
TARGET_DZ = 3

TARGET_RK = D

Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

7 - 3 - YES

RK - 1 - YES

https://contest.yandex.ru/contest/36255/enter

### Module 2
Expand All @@ -32,5 +34,13 @@ https://contest.yandex.ru/contest/36255/enter

5 - all -

RK - 1 - YES

RK - 2 - YES

RK - 3 - YES

RK - 4 - YES/NO


https://contest.yandex.ru/contest/37595/enter/
251 changes: 251 additions & 0 deletions module_2/3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
#include <iostream>
#include <vector>
#include <cassert>
#include <queue>


// Постройте B-дерево минимального порядка t и выведите его по слоям.
// В качестве ключа используются числа, лежащие в диапазоне 0..2^32 -1

template<typename T>
struct Node {
bool leaf;

std::vector <T> keys;
std::vector<Node *> children;

Node(bool leaf) : leaf(leaf) {}

~Node();

friend std::ostream& operator<<(std::ostream &os, const Node<T> &it) {
for (auto &data: it.keys) {
os << data << " ";
}

return os;
}

Node &operator = (const Node &other) = default;
};

template<typename T>
Node<T>::~Node() {
for (auto child: children) {
delete child;
}
}

template<typename T>
class Less {
public:
bool operator()(const T &l, const T &r) const {
return l < r;
}
};

template<typename T, typename CompareRule = Less<T>>
class BTree {
CompareRule rule;

size_t t;

size_t size;

Node<T> *root;

bool IsNodeFull(Node<T> *node);

void SplitChild(Node<T> *node, size_t index);

void AddNonFull(Node<T> *node, const T &data);

void DebugPrint(Node<T> *node, size_t indent);

public:
BTree(const size_t min_degree) : t(min_degree), root(nullptr), size(0) { assert(min_degree >= 2); }

~BTree();

void Add(const T &data);

void DebugPrint();

void Print();

size_t Size() const;
};

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::Print() {
std::queue < Node<T> * > s;

s.push(root);

while (!s.empty()) {
Node<T> *tmp = s.front();
s.pop();

std::cout << *tmp;

for (size_t i = 0; i < tmp->children.size(); ++i) {
s.push(tmp->children[i]);
}
}
}

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::SplitChild(Node<T> *node, size_t index) {
Node<T> *new_child = new Node<T>(node->children[index]->leaf);
++size;

for (size_t i = 0; i < t - 1; ++i) {
new_child->keys.push_back(node->children[index]->keys[i + t]);
}

for (size_t i = 0; i < t - 1; ++i) {
node->children[index]->keys.pop_back();
}

ssize_t pos = node->keys.size() - 1;

T mid = node->children[index]->keys[t - 1];

node->keys.resize(node->keys.size() + 1);
while (pos >= 0 && mid < node->keys[pos]) {
node->keys[pos + 1] = node->keys[pos];

--pos;
}

node->keys[pos + 1] = mid;

if (!node->children[index]->leaf) {
size_t count_child = node->children[index]->children.size() - 1;

for (size_t i = 0; i < t; ++i) {
new_child->children.push_back(node->children[index]->children[i + t]);
}


for (size_t i = 0; i < t; ++i) {
node->children[index]->children.pop_back();
}
}

node->children[index]->keys.pop_back();

node->children.push_back(new_child);
}

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::DebugPrint() {
DebugPrint(root, 0);
}

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::DebugPrint(Node<T> *node, size_t indent) {
std::cout << std::string(indent, ' ');
std::cout << "data: [";

for (auto it = node->keys.begin(); it != node->keys.end(); it++) {
std::cout << (*it);
if (it + 1 != node->keys.end())
std::cout << ", ";
}

std::cout << "]" << std::endl;

for (auto child: node->children) {
DebugPrint(child, indent + 4);
}
}

template<typename T, typename CompareRule>
BTree<T, CompareRule>::~BTree() {
if (root) {
delete root;
}
}

template<typename T, typename CompareRule>
bool BTree<T, CompareRule>::IsNodeFull(Node<T> *node) {
return node->keys.size() == 2 * t - 1;
}

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::Add(const T &data) {
if (!root) {
root = new Node<T>(true);
++size;
}

if (IsNodeFull(root)) {
Node<T> *new_root = new Node<T>(false);
++size;

new_root->children.push_back(root);

root = new_root;

SplitChild(root, 0);
}

AddNonFull(root, data);
}

template<typename T, typename CompareRule>
void BTree<T, CompareRule>::AddNonFull(Node<T> *node, const T &data) {
ssize_t pos = node->keys.size() - 1;

if (node->leaf) {
node->keys.resize(node->keys.size() + 1);

while (pos >= 0 && data < node->keys[pos]) {
node->keys[pos + 1] = node->keys[pos];

--pos;
}

node->keys[pos + 1] = data;
} else {
while (pos >= 0 && data < node->keys[pos]) {
--pos;
}

if (IsNodeFull(node->children[pos + 1])) {
SplitChild(node, pos + 1);

if (data > node->keys[pos + 1]) {
++pos;
}
}

AddNonFull(node->children[pos + 1], data);
}
}


void run(std::istream &input, std::ostream &output) {
size_t n;

input >> n;

BTree<size_t> b_tree(n);

size_t tmp;

while (input >> tmp) {
b_tree.Add(tmp);
}

b_tree.DebugPrint();

b_tree.Print();
}

int main() {
run(std::cin, std::cout);

return EXIT_SUCCESS;
}
2 changes: 2 additions & 0 deletions module_2/Tests/3/1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2
0 1 2 3 4 5 6 7 8 9
2 changes: 2 additions & 0 deletions module_2/Tests/3/2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
4
0 1 2 3 4 5 6 7 8 9

0 comments on commit 985493b

Please sign in to comment.