#include #include #include #include using namespace std; class CTree{ public: CTree() = default; CTree(const CTree & src) = delete; CTree & operator = (const CTree & src) = delete; ~CTree(){ delete m_Root; } bool isSet(const string & key){ CNode* i = nullptr; CNode* n = m_Root; do { std::swap(i, n); if (i->m_Key == key) return true; n = i->m_Key < key ? i->m_R : i->m_L; } while (n); return false; } bool insert(const string & key, const string & val){ if (!m_Root) { m_Root = new CNode(key, val); m_First = m_Last = m_Root; return true; } CNode* i = nullptr; CNode* n = m_Root; do { std::swap(i, n); if (i->m_Key == key) return false; n = i->m_Key < key ? i->m_R : i->m_L; } while (n); n = new CNode(key, val); if (i->m_Key < key) { i->m_R = n; } else { i->m_L = n; } return m_Last = m_Last->m_NextOrder = n; } friend ostream & operator << (ostream & os, const CTree & src){ src.print(os); return os; } protected: class CNode{ public: CNode(const string & key, const string & val) :m_Key(key), m_Val(val) {} ~CNode() { delete m_L; delete m_R; } string m_Key, m_Val; CNode * m_L = nullptr, * m_R = nullptr; CNode * m_NextOrder = nullptr; }; CNode * m_Root = nullptr; CNode * m_First = nullptr, * m_Last = nullptr; void print( ostream & os ) const { os << "{"; for (CNode* i = m_First; i; i = i->m_NextOrder) { os << i->m_Key << " => " << i->m_Val; if (i != m_Last) os << ", "; } os << "}"; } friend int main(); }; int main(void){ CTree t; stringstream ss; ss << t; assert(ss.str() == "{}"); ss.clear(); ss.str(""); assert(t.insert("PA1", "done")); assert(t.m_First == t.m_Last); assert(t.m_First->m_Key == "PA1"); assert(!t.isSet("UOS")); assert(t.insert("PA2", "fail")); assert(t.insert("UOS", "funny")); ss << t; assert(ss.str() == "{PA1 => done, PA2 => fail, UOS => funny}"); ss.clear(); ss.str(""); assert(t.m_Root->m_L== nullptr); assert(t.m_Last->m_Key == "UOS"); assert(t.m_Root->m_R->m_Key == "PA2"); assert(t.m_Root->m_R->m_L == nullptr); assert(t.m_Root->m_R->m_R->m_Key == "UOS"); assert(t.m_First->m_NextOrder->m_NextOrder == t.m_Last); assert(t.isSet("PA2")); assert(t.insert("CAO", "lul")); assert(t.insert("LIN", "F")); assert(t.m_Root->m_L->m_Key == "CAO"); assert(t.m_Root->m_L->m_L == nullptr); assert(t.m_Root->m_L->m_R->m_Key == "LIN"); assert(t.m_Last == t.m_Root->m_L->m_R ); assert(t.m_Root->m_L->m_R->m_L == nullptr); assert(t.m_First->m_NextOrder->m_NextOrder->m_NextOrder->m_NextOrder = t.m_Root->m_L->m_R); assert(t.isSet("LIN")); ss << t; assert(ss.str() == "{PA1 => done, PA2 => fail, UOS => funny, CAO => lul, LIN => F}"); ss.clear(); ss.str(""); assert(t.insert("SAP", "shit")); assert(t.m_Root->m_R->m_R->m_L->m_Key == "SAP"); assert(t.m_Last == t.m_Root->m_R->m_R->m_L); ss << t; assert(ss.str() == "{PA1 => done, PA2 => fail, UOS => funny, CAO => lul, LIN => F, SAP => shit}"); ss.clear(); ss.str(""); assert(!t.isSet("PA3")); assert(t.isSet("LIN")); assert(t.isSet("SAP")); std::cout << "success!\n"; return 0; }