diff --git a/set.cpp b/set.cpp new file mode 100644 index 0000000..36af565 --- /dev/null +++ b/set.cpp @@ -0,0 +1,301 @@ +/** + * Implementujte metodu insert (vkládání), erase (mazání prvků + * ze stromu a zároveň je potřeba uchovat správné pořádí podle + * data vkládání) a vlastní destruktor, ostatní metody jsou + * naimplentované. Kopírující konstruktor i operátor přiřazení + * zakázán. Není povolené si přidat žádnou členskou proměnnou, + * ale lze naimplementovat vlastní pomocné metody. + * + * Za správnost šablony neručím :-). + */ + +#include +#include + + // https://fit-wiki.cz/%C5%A1kola/p%C5%99edm%C4%9Bty/bi-pa2/pa2_zkou%C5%A1ka_2022-06-16 + +using namespace std; + +class CTree +{ + public: + CTree() = default; + ~CTree() { + CNode* i = m_First; + while (i) { + CNode* j = i->m_NextOrder; + delete i; + i = j; + } + } + + + + CTree(const CTree &src) = delete; + + bool operator=(const CTree &other) = delete; + + bool isSet(string key) { + CNode * n = m_Root; + while (n) { + if (key == n->m_Key) + return true; + else if (key > n->m_Key) + n = n->m_R; + else + n = n->m_L; + } + return false; + } + + bool insert(string key) { + if (!m_Root) + return m_Root = m_First = m_Last = new CNode(key); + + CNode* i = nullptr; + CNode* n = m_Root; + while (n) { + if (key == n->m_Key) { + return false; + } else if (key > n->m_Key) { + i = n; + n = n->m_R; + } else { + i = n; + n = n->m_L; + } + } + + n = new CNode(key); + if (key > i->m_Key) + i->m_R = n; + else + i->m_L = n; + + n->m_PrevOrder = m_Last; + m_Last = m_Last->m_NextOrder = n; + return true; + } + + bool erase(string key) { + CNode** p = &m_Root; + CNode* n = m_Root; + while (n) { + if (key == n->m_Key) + goto found; + else if (key > n->m_Key) { + p = &n->m_R; + n = n->m_R; + } else { + p = &n->m_L; + n = n->m_L; + } + } + return false; + + found: + if (!(n->m_L && n->m_R)) { // one or none child + *p = (CNode*)((ptrdiff_t)n->m_L | (ptrdiff_t)n->m_R); + } else { + CNode* ts = n->m_L; + CNode** tsp = &n->m_L; + while (ts->m_R) { + tsp = &ts->m_R; + ts = ts->m_R; + } + swapTree( n, ts ); + *tsp = ts->m_L; + n = ts; + } + eraseList(n); + delete n; + return true; + } + + protected: + class CNode { + public: + CNode(string key) : m_Key(key) {} + string m_Key; + CNode * m_L = nullptr; + CNode * m_R = nullptr; + CNode * m_PrevOrder = nullptr; + CNode * m_NextOrder = nullptr; + }; + CNode * m_Root = nullptr; + CNode * m_First = nullptr; + CNode * m_Last = nullptr; + + void swapTree( CNode* a, CNode* b ) { + if (a == m_Last) m_Last = b; + else if (b == m_Last) m_Last = a; + + if (a == m_First) m_First = b; + else if (b == m_First) m_First = a; + + if (a->m_NextOrder) a->m_NextOrder->m_PrevOrder = b; + if (a->m_PrevOrder) a->m_PrevOrder->m_NextOrder = b; + if (b->m_NextOrder) b->m_NextOrder->m_PrevOrder = a; + if (b->m_PrevOrder) b->m_PrevOrder->m_NextOrder = a; + + std::swap(a->m_NextOrder, b->m_NextOrder); + std::swap(a->m_PrevOrder, b->m_PrevOrder); + std::swap(a->m_Key, b->m_Key); + } + + void eraseList( CNode* a ) { + if (a->m_PrevOrder) + a->m_PrevOrder->m_NextOrder = a->m_NextOrder; + else + m_First = a->m_NextOrder; + + if (a->m_NextOrder) + a->m_NextOrder->m_PrevOrder = a->m_PrevOrder; + else + m_Last = a->m_PrevOrder; + } +}; + +class CTester : public CTree +{ + public: + CTester () = default; + void test() + { + CTester t0; + assert(t0.insert("PA1")==true); + assert(t0.m_First->m_Key=="PA1" && t0.m_First->m_NextOrder == nullptr); + assert(t0.isSet("PA1")==true); + assert(t0.insert("UOS")==true); + assert(t0.insert("PA2")==true); + assert(t0.isSet("PA2")==true); + assert(t0.isSet("PA3")==false); + + assert(t0.insert("PA2")==false); + assert(t0.insert("CAO")==true); + assert(t0.insert("LIN")==true); + assert(t0.insert("AAG")==true); + assert(t0.insert("AG1")==true); + assert(t0.insert("ZDM")==true); + + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "UOS" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "CAO" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AAG" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "ZDM"); + + assert(t0.m_Last->m_Key == "ZDM" + && t0.m_Last->m_PrevOrder->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "AAG" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "CAO" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "UOS" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + + assert(t0.erase("")==false); + + assert(t0.erase("ZDM")==true); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "UOS" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "CAO" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AAG" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "AAG" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "CAO" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "UOS" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("ZDM")==false); + + assert(t0.erase("AAG")==true); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "UOS" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "CAO" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "CAO" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "UOS" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("AAG")==false); + + assert(t0.erase("CAO")==true); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "UOS" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "UOS" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("CAO")==false); + + assert(t0.erase("UOS")==true); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("UOS")==false); + + assert(t0.erase("UOS")==false); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "LIN" + && t0.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "LIN" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("UOS")==false); + + assert(t0.erase("LIN")==true); + assert(t0.m_First->m_Key == "PA1" + && t0.m_First->m_NextOrder->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "PA2" + && t0.m_Last->m_PrevOrder->m_PrevOrder->m_Key == "PA1"); + assert(t0.isSet("LIN")==false); + + assert(t0.erase("PA1")==true); + assert(t0.m_First->m_Key == "PA2" + && t0.m_First->m_NextOrder->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1" + && t0.m_Last->m_PrevOrder->m_Key == "PA2"); + assert(t0.isSet("PA1")==false); + + assert(t0.erase("PA2")==true); + assert(t0.m_First->m_Key == "AG1"); + assert(t0.m_Last->m_Key == "AG1"); + assert(t0.isSet("PA2")==false); + + assert(t0.erase("AG1")==true); + assert(t0.m_First == t0.m_Last); + assert(t0.isSet("AG1")==false); + } +}; + #include +int main ( ) +{ + CTester t; + t.test(); + std::cout << "success!\n"; + return EXIT_SUCCESS; +} \ No newline at end of file