/* Logic1: Recursive Logic2: Iterative */ #include <iostream> #include <deque> #include <vector> #include <utility> using namespace std; class node; typedef deque<node*> nodePtrDeque; typedef vector<int> intVector; typedef const vector<int>& constIntVectorRef; typedef vector<int>::const_iterator constIntVectorItr; typedef pair<constIntVectorItr, constIntVectorItr> itrPair; typedef pair<constIntVectorItr, constIntVectorItr>* itrPairPtr; class node { public: int val; node * right; node * left; node(int v):val(v), right(NULL), left(NULL){}; }; constIntVectorItr mid(constIntVectorItr s, constIntVectorItr e) { if (s > e) { return e + 1; } return ((e - s) % 2) ? (s + (e - s + 1) / 2) : (s + (e - s) / 2); }; node * helper(constIntVectorRef vec, constIntVectorItr s, constIntVectorItr e) { if (s > e) { return NULL; } else { constIntVectorItr m = mid(s, e); node *n = new node(*m); n->left = helper(vec, s, m - 1); n->right = helper(vec, m + 1, e); return n; } }; node* Logic1(constIntVectorRef vec) { if (vec.empty()) return NULL; /* uniformly use iterator of C++ feature. If use pointers, then do keep them consistent. */ return helper(vec, vec.begin(), vec.end() - 1); }; node* Logic2(constIntVectorRef vec) { if (vec.empty()) return NULL; node *root = NULL; constIntVectorItr s = vec.begin(); constIntVectorItr e = vec.end() - 1; vector<itrPairPtr> stack; //stack the ranges nodePtrDeque nstack; //stack the parent for a range stack.push_back(new itrPair(s, e)); nstack.push_back(NULL); while (! stack.empty()) { itrPairPtr p = stack.back(); stack.pop_back(); node* anc = nstack.back(); nstack.pop_back(); if (p->first <= p->second) { constIntVectorItr m = mid(p->first, p->second); node* n = new node(*m); //cout << *m << endl; if (p->first == s && p->second == e) { root = n; } else { if (anc->val >= n->val && anc->left == NULL) { anc->left = n; } else if (anc->val <= n->val && anc->right== NULL) { anc->right = n; } } stack.push_back(new itrPair(p->first, m - 1)); nstack.push_back(n); stack.push_back(new itrPair(m + 1, p->second)); nstack.push_back(n); } delete p; } return root; } /* This is better in logic */ node * Logic2_v2(const vector<int>& vec) { if (vec.empty()) return NULL; typedef pair<const vector<int>::const_iterator, const vector<int>::const_iterator> mypair; const vector<int>::const_iterator s = vec.begin(); const vector<int>::const_iterator e = vec.end() - 1; vector<mypair* > stack; //stack the ranges vector<node *> nstack; //stack the parent for a range stack.push_back(new mypair(s, e)); const vector<int>::const_iterator m = mid(s, e); node* root = new node(*m); nstack.push_back(root); while (! stack.empty()) { mypair* p = stack.back(); stack.pop_back(); node* anc = nstack.back(); nstack.pop_back(); if (p->first <= p->second) { const vector<int>::const_iterator m = mid(p->first, p->second); const vector<int>::const_iterator left = mid(p->first, m - 1); const vector<int>::const_iterator right = mid(m + 1, p->second); if (left > m - 1) { anc->left = NULL; } else { node *ancleft = new node(*left); anc->left = ancleft; nstack.push_back(ancleft); stack.push_back(new mypair(p->first, m - 1)); } if (right > p->second) { anc->right = NULL; } else { node *ancright = new node(*right); anc->right = ancright; nstack.push_back(ancright); stack.push_back(new mypair(m + 1, p->second)); } } delete p; } return root; } int main() { int arr[10] = {0,1,2,3,4,5,6,7,8,9}; intVector vec(arr, arr + 10); //node *root = Logic1(vec); //node *root = Logic2(vec); node *root = Logic2_v2(vec); //traverse and deconstruct node *n = NULL; nodePtrDeque queue; queue.push_back(root); /* set the NULL as level delimiter, made mistake here, be carefull about the logic */ queue.push_back(NULL); while (! queue.empty()) { n = queue.front(); queue.pop_front(); if (n == NULL) { cout << endl; if (! queue.empty()) queue.push_back(NULL); } else { cout << n->val << ' '; if (n->left != NULL) { queue.push_back(n->left); } if (n->right != NULL) { queue.push_back(n->right); } delete n; n = NULL; } } return 0; };