diff --git a/bst.cpp b/bst.cpp new file mode 100644 index 0000000..47cd411 --- /dev/null +++ b/bst.cpp @@ -0,0 +1,167 @@ +#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; +} \ No newline at end of file