#include <iostream>
#include <vector>
using namespace std;
class Tree
{
public:
Tree() : root(NONE) { }
~Tree() { }
void add(const string& data);
void remove(const string& data);
string dump();
private:
typedef uint32_t index;
static const index NONE = static_cast<index>(-1);
class Node
{
public:
Node(const string& data, index parent, index left, index right) :
data(data), parent(parent), left(left), right(right)
{
}
string data;
index parent, left, right;
};
index find(const string& data, index& parent, bool& left);
void remove_replace(index inode);
index leftmost(index inode);
string dump(index inode, const string& tab, const string& tabs);
vector<Node> nodes;
index root;
};
const Tree::index Tree::NONE;
void Tree::add(const string& data)
{
index inode = nodes.size(), iparent;
bool left;
if (find(data, iparent, left) != NONE) throw runtime_error("дубликат: " + data);
nodes.emplace_back(data, iparent, NONE, NONE);
(iparent == NONE ? root : left ? nodes[iparent].left : nodes[iparent].right) = inode;
}
void Tree::remove(const string& data)
{
index inode, iparent;
bool left;
if ((inode = find(data, iparent, left)) == NONE) throw runtime_error("не найдено: " + data);
Node& node = nodes[inode];
if (node.left != NONE && node.right != NONE)
{
// удаление элемента с 2 детьми
index rlm = leftmost(node.right), rlmp = nodes[rlm].parent, rlmr = nodes[rlm].right;
node.data = move(nodes[rlm].data);
(rlm == nodes[rlmp].left ? nodes[rlmp].left : nodes[rlmp].right) = rlmr;
if (rlmr != NONE) nodes[rlmr].parent = rlmp;
remove_replace(rlm);
} else
{
// удаление элемента с 0 или 1 детьми
index maybe_child = node.left != NONE ? node.left : node.right;
(iparent == NONE ? root : left ? nodes[iparent].left : nodes[iparent].right) = maybe_child;
if (maybe_child != NONE) nodes[maybe_child].parent = iparent;
remove_replace(inode);
}
}
string Tree::dump()
{
return root == NONE ? "<пусто>" : dump(root, "\t", "");
}
Tree::index Tree::find(const string& data, index& iparent, bool& left)
{
iparent = NONE;
index inode = root;
while (inode != NONE)
{
Node& node = nodes[inode];
int cmp = data.compare(node.data);
if (cmp == 0) break;
iparent = inode;
inode = cmp < 0 ? node.left : node.right;
left = cmp < 0;
}
return inode;
}
// Удаляет узел inode из хранилища узлов,
// заменяя его последним и исправляя индексы ссылавшихся на последний.
void Tree::remove_replace(index inode)
{
index ilast = nodes.size() - 1;
if (inode != ilast)
{
Node& node = nodes[inode];
node = move(nodes[ilast]);
if (node.parent == NONE)
root = inode;
else
{
Node& parent = nodes[node.parent];
(ilast == parent.left ? parent.left : parent.right) = inode;
}
if (node.left != NONE) nodes[node.left].parent = inode;
if (node.right != NONE) nodes[node.right].parent = inode;
}
nodes.pop_back();
}
Tree::index Tree::leftmost(index inode)
{
for (index next; (next = nodes[inode].left) != NONE; inode = next) ;
return inode;
}
string Tree::dump(index inode, const string& tab, const string& tabs)
{
Node& node = nodes[inode];
string r = node.data + " (#" + to_string(inode) + ", parent = " + (node.parent == NONE ? "NONE" : "#" + to_string(node.parent)) + ")";
for (int ic = 0; ic < 2; ic++)
{
index child = ic == 0 ? node.left : node.right;
if (child != NONE)
r += "\n" + tabs + tab + (ic == 0 ? "L" : "R") + " = " + dump(child, tab, tabs + tab);
}
return r;
}
int main()
{
string ops[] =
{
"+555",
"+444",
"+666",
"+321",
"+445",
"+777",
"+600",
"-гетеросексуальность",
"+600",
"-555",
"-777",
"-444",
"-445",
"-600",
"-321",
"-666",
};
Tree tree;
cout << tree.dump() << endl << endl;
for (const auto& op : ops)
{
bool add = op[0] == '+';
string arg = op.substr(1);
cout << (add ? "Добавление" : "Удаление") << " " << arg << endl;
try
{
if (add)
tree.add(arg);
else
tree.remove(arg);
} catch (const exception& err)
{
cout << err.what() << endl << endl;
continue;
}
cout << tree.dump() << endl << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgVHJlZQp7CnB1YmxpYzoKCVRyZWUoKSA6IHJvb3QoTk9ORSkgeyB9Cgl+VHJlZSgpIHsgfQoKCXZvaWQgYWRkKGNvbnN0IHN0cmluZyYgZGF0YSk7Cgl2b2lkIHJlbW92ZShjb25zdCBzdHJpbmcmIGRhdGEpOwoJc3RyaW5nIGR1bXAoKTsKCnByaXZhdGU6Cgl0eXBlZGVmIHVpbnQzMl90IGluZGV4OwoJc3RhdGljIGNvbnN0IGluZGV4IE5PTkUgPSBzdGF0aWNfY2FzdDxpbmRleD4oLTEpOwoKCWNsYXNzIE5vZGUKCXsKCXB1YmxpYzoKCQlOb2RlKGNvbnN0IHN0cmluZyYgZGF0YSwgaW5kZXggcGFyZW50LCBpbmRleCBsZWZ0LCBpbmRleCByaWdodCkgOgoJCQlkYXRhKGRhdGEpLCBwYXJlbnQocGFyZW50KSwgbGVmdChsZWZ0KSwgcmlnaHQocmlnaHQpCgkJewoJCX0KCgkJc3RyaW5nIGRhdGE7CgkJaW5kZXggcGFyZW50LCBsZWZ0LCByaWdodDsKCX07CglpbmRleCBmaW5kKGNvbnN0IHN0cmluZyYgZGF0YSwgaW5kZXgmIHBhcmVudCwgYm9vbCYgbGVmdCk7Cgl2b2lkIHJlbW92ZV9yZXBsYWNlKGluZGV4IGlub2RlKTsKCWluZGV4IGxlZnRtb3N0KGluZGV4IGlub2RlKTsKCXN0cmluZyBkdW1wKGluZGV4IGlub2RlLCBjb25zdCBzdHJpbmcmIHRhYiwgY29uc3Qgc3RyaW5nJiB0YWJzKTsKCgl2ZWN0b3I8Tm9kZT4gbm9kZXM7CglpbmRleCByb290Owp9OwoKY29uc3QgVHJlZTo6aW5kZXggVHJlZTo6Tk9ORTsKCnZvaWQgVHJlZTo6YWRkKGNvbnN0IHN0cmluZyYgZGF0YSkKewoJaW5kZXggaW5vZGUgPSBub2Rlcy5zaXplKCksIGlwYXJlbnQ7Cglib29sIGxlZnQ7CglpZiAoZmluZChkYXRhLCBpcGFyZW50LCBsZWZ0KSAhPSBOT05FKSB0aHJvdyBydW50aW1lX2Vycm9yKCLQtNGD0LHQu9C40LrQsNGCOiAiICsgZGF0YSk7CgoJbm9kZXMuZW1wbGFjZV9iYWNrKGRhdGEsIGlwYXJlbnQsIE5PTkUsIE5PTkUpOwoJKGlwYXJlbnQgPT0gTk9ORSA/IHJvb3QgOiBsZWZ0ID8gbm9kZXNbaXBhcmVudF0ubGVmdCA6IG5vZGVzW2lwYXJlbnRdLnJpZ2h0KSA9IGlub2RlOwp9Cgp2b2lkIFRyZWU6OnJlbW92ZShjb25zdCBzdHJpbmcmIGRhdGEpCnsKCWluZGV4IGlub2RlLCBpcGFyZW50OwoJYm9vbCBsZWZ0OwoJaWYgKChpbm9kZSA9IGZpbmQoZGF0YSwgaXBhcmVudCwgbGVmdCkpID09IE5PTkUpIHRocm93IHJ1bnRpbWVfZXJyb3IoItC90LUg0L3QsNC50LTQtdC90L46ICIgKyBkYXRhKTsKCglOb2RlJiBub2RlID0gbm9kZXNbaW5vZGVdOwoJaWYgKG5vZGUubGVmdCAhPSBOT05FICYmIG5vZGUucmlnaHQgIT0gTk9ORSkKCXsKCQkvLyDRg9C00LDQu9C10L3QuNC1INGN0LvQtdC80LXQvdGC0LAg0YEgMiDQtNC10YLRjNC80LgKCQlpbmRleCBybG0gPSBsZWZ0bW9zdChub2RlLnJpZ2h0KSwgcmxtcCA9IG5vZGVzW3JsbV0ucGFyZW50LCBybG1yID0gbm9kZXNbcmxtXS5yaWdodDsKCQlub2RlLmRhdGEgPSBtb3ZlKG5vZGVzW3JsbV0uZGF0YSk7CgkJKHJsbSA9PSBub2Rlc1tybG1wXS5sZWZ0ID8gbm9kZXNbcmxtcF0ubGVmdCA6IG5vZGVzW3JsbXBdLnJpZ2h0KSA9IHJsbXI7CgkJaWYgKHJsbXIgIT0gTk9ORSkgbm9kZXNbcmxtcl0ucGFyZW50ID0gcmxtcDsKCQlyZW1vdmVfcmVwbGFjZShybG0pOwoJfSBlbHNlCgl7CgkJLy8g0YPQtNCw0LvQtdC90LjQtSDRjdC70LXQvNC10L3RgtCwINGBIDAg0LjQu9C4IDEg0LTQtdGC0YzQvNC4CgkJaW5kZXggbWF5YmVfY2hpbGQgPSBub2RlLmxlZnQgIT0gTk9ORSA/IG5vZGUubGVmdCA6IG5vZGUucmlnaHQ7CgkJKGlwYXJlbnQgPT0gTk9ORSA/IHJvb3QgOiBsZWZ0ID8gbm9kZXNbaXBhcmVudF0ubGVmdCA6IG5vZGVzW2lwYXJlbnRdLnJpZ2h0KSA9IG1heWJlX2NoaWxkOwoJCWlmIChtYXliZV9jaGlsZCAhPSBOT05FKSBub2Rlc1ttYXliZV9jaGlsZF0ucGFyZW50ID0gaXBhcmVudDsKCQlyZW1vdmVfcmVwbGFjZShpbm9kZSk7Cgl9Cn0KCnN0cmluZyBUcmVlOjpkdW1wKCkKewoJcmV0dXJuIHJvb3QgPT0gTk9ORSA/ICI80L/Rg9GB0YLQvj4iIDogZHVtcChyb290LCAiXHQiLCAiIik7Cn0KClRyZWU6OmluZGV4IFRyZWU6OmZpbmQoY29uc3Qgc3RyaW5nJiBkYXRhLCBpbmRleCYgaXBhcmVudCwgYm9vbCYgbGVmdCkKewoJaXBhcmVudCA9IE5PTkU7CglpbmRleCBpbm9kZSA9IHJvb3Q7Cgl3aGlsZSAoaW5vZGUgIT0gTk9ORSkKCXsKCQlOb2RlJiBub2RlID0gbm9kZXNbaW5vZGVdOwoJCWludCBjbXAgPSBkYXRhLmNvbXBhcmUobm9kZS5kYXRhKTsKCQlpZiAoY21wID09IDApIGJyZWFrOwoJCWlwYXJlbnQgPSBpbm9kZTsKCQlpbm9kZSA9IGNtcCA8IDAgPyBub2RlLmxlZnQgOiBub2RlLnJpZ2h0OwoJCWxlZnQgPSBjbXAgPCAwOwoJfQoJcmV0dXJuIGlub2RlOwp9CgovLyDQo9C00LDQu9GP0LXRgiDRg9C30LXQuyBpbm9kZSDQuNC3INGF0YDQsNC90LjQu9C40YnQsCDRg9C30LvQvtCyLAovLyDQt9Cw0LzQtdC90Y/RjyDQtdCz0L4g0L/QvtGB0LvQtdC00L3QuNC8INC4INC40YHQv9GA0LDQstC70Y/RjyDQuNC90LTQtdC60YHRiyDRgdGB0YvQu9Cw0LLRiNC40YXRgdGPINC90LAg0L/QvtGB0LvQtdC00L3QuNC5Lgp2b2lkIFRyZWU6OnJlbW92ZV9yZXBsYWNlKGluZGV4IGlub2RlKQp7CglpbmRleCBpbGFzdCA9IG5vZGVzLnNpemUoKSAtIDE7CglpZiAoaW5vZGUgIT0gaWxhc3QpCgl7CgkJTm9kZSYgbm9kZSA9IG5vZGVzW2lub2RlXTsKCQlub2RlID0gbW92ZShub2Rlc1tpbGFzdF0pOwoKCQlpZiAobm9kZS5wYXJlbnQgPT0gTk9ORSkKCQkJcm9vdCA9IGlub2RlOwoJCWVsc2UKCQl7CgkJCU5vZGUmIHBhcmVudCA9IG5vZGVzW25vZGUucGFyZW50XTsKCQkJKGlsYXN0ID09IHBhcmVudC5sZWZ0ID8gcGFyZW50LmxlZnQgOiBwYXJlbnQucmlnaHQpID0gaW5vZGU7CgkJfQoJCWlmIChub2RlLmxlZnQgIT0gTk9ORSkgbm9kZXNbbm9kZS5sZWZ0XS5wYXJlbnQgPSBpbm9kZTsKCQlpZiAobm9kZS5yaWdodCAhPSBOT05FKSBub2Rlc1tub2RlLnJpZ2h0XS5wYXJlbnQgPSBpbm9kZTsKCX0KCW5vZGVzLnBvcF9iYWNrKCk7Cn0KClRyZWU6OmluZGV4IFRyZWU6OmxlZnRtb3N0KGluZGV4IGlub2RlKQp7Cglmb3IgKGluZGV4IG5leHQ7IChuZXh0ID0gbm9kZXNbaW5vZGVdLmxlZnQpICE9IE5PTkU7IGlub2RlID0gbmV4dCkgOwoJcmV0dXJuIGlub2RlOwp9CgpzdHJpbmcgVHJlZTo6ZHVtcChpbmRleCBpbm9kZSwgY29uc3Qgc3RyaW5nJiB0YWIsIGNvbnN0IHN0cmluZyYgdGFicykKewoJTm9kZSYgbm9kZSA9IG5vZGVzW2lub2RlXTsKCXN0cmluZyByID0gbm9kZS5kYXRhICsgIiAoIyIgKyB0b19zdHJpbmcoaW5vZGUpICsgIiwgcGFyZW50ID0gIiArIChub2RlLnBhcmVudCA9PSBOT05FID8gIk5PTkUiIDogIiMiICsgdG9fc3RyaW5nKG5vZGUucGFyZW50KSkgKyAiKSI7Cglmb3IgKGludCBpYyA9IDA7IGljIDwgMjsgaWMrKykKCXsKCQlpbmRleCBjaGlsZCA9IGljID09IDAgPyBub2RlLmxlZnQgOiBub2RlLnJpZ2h0OwoJCWlmIChjaGlsZCAhPSBOT05FKQoJCQlyICs9ICJcbiIgKyB0YWJzICsgdGFiICsgKGljID09IDAgPyAiTCIgOiAiUiIpICsgIiA9ICIgKyBkdW1wKGNoaWxkLCB0YWIsIHRhYnMgKyB0YWIpOwoJfQoJcmV0dXJuIHI7Cn0KCmludCBtYWluKCkKewoJc3RyaW5nIG9wc1tdID0KCXsKCQkiKzU1NSIsCgkJIis0NDQiLAoJCSIrNjY2IiwKCQkiKzMyMSIsCgkJIis0NDUiLAoJCSIrNzc3IiwKCQkiKzYwMCIsCgkJIi3Qs9C10YLQtdGA0L7RgdC10LrRgdGD0LDQu9GM0L3QvtGB0YLRjCIsCgkJIis2MDAiLAoJCSItNTU1IiwKCQkiLTc3NyIsCgkJIi00NDQiLAoJCSItNDQ1IiwKCQkiLTYwMCIsCgkJIi0zMjEiLAoJCSItNjY2IiwKCX07CgoJVHJlZSB0cmVlOwoJY291dCA8PCB0cmVlLmR1bXAoKSA8PCBlbmRsIDw8IGVuZGw7Cglmb3IgKGNvbnN0IGF1dG8mIG9wIDogb3BzKQoJewoJCWJvb2wgYWRkID0gb3BbMF0gPT0gJysnOwoJCXN0cmluZyBhcmcgPSBvcC5zdWJzdHIoMSk7CgkJY291dCA8PCAoYWRkID8gItCU0L7QsdCw0LLQu9C10L3QuNC1IiA6ICLQo9C00LDQu9C10L3QuNC1IikgPDwgIiAiIDw8IGFyZyA8PCBlbmRsOwoKCQl0cnkKCQl7CgkJCWlmIChhZGQpCgkJCQl0cmVlLmFkZChhcmcpOwoJCQllbHNlCgkJCQl0cmVlLnJlbW92ZShhcmcpOwoJCX0gY2F0Y2ggKGNvbnN0IGV4Y2VwdGlvbiYgZXJyKQoJCXsKCQkJY291dCA8PCBlcnIud2hhdCgpIDw8IGVuZGwgPDwgZW5kbDsKCQkJY29udGludWU7CgkJfQoKCQljb3V0IDw8IHRyZWUuZHVtcCgpIDw8IGVuZGwgPDwgZW5kbDsKCX0KCXJldHVybiAwOwp9
<пусто>
Добавление 555
555 (#0, parent = NONE)
Добавление 444
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
Добавление 666
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
R = 666 (#2, parent = #0)
Добавление 321
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 666 (#2, parent = #0)
Добавление 445
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 445 (#4, parent = #1)
R = 666 (#2, parent = #0)
Добавление 777
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 445 (#4, parent = #1)
R = 666 (#2, parent = #0)
R = 777 (#5, parent = #2)
Добавление 600
555 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 445 (#4, parent = #1)
R = 666 (#2, parent = #0)
L = 600 (#6, parent = #2)
R = 777 (#5, parent = #2)
Удаление гетеросексуальность
не найдено: гетеросексуальность
Добавление 600
дубликат: 600
Удаление 555
600 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 445 (#4, parent = #1)
R = 666 (#2, parent = #0)
R = 777 (#5, parent = #2)
Удаление 777
600 (#0, parent = NONE)
L = 444 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 445 (#4, parent = #1)
R = 666 (#2, parent = #0)
Удаление 444
600 (#0, parent = NONE)
L = 445 (#1, parent = #0)
L = 321 (#3, parent = #1)
R = 666 (#2, parent = #0)
Удаление 445
600 (#0, parent = NONE)
L = 321 (#1, parent = #0)
R = 666 (#2, parent = #0)
Удаление 600
666 (#0, parent = NONE)
L = 321 (#1, parent = #0)
Удаление 321
666 (#0, parent = NONE)
Удаление 666
<пусто>