// intervalTree.cpp -- 区间树实现文件 #include "stdafx.h" #include "intervalTree.h" namespace tree { // private: bool IntervalTree :: m_Overlap (const Item min, const Item max) const { if (m_min <= max) { if (min <= m_max) return true ; else return false ; } else return false ; } Item IntervalTree :: m_Max (const Item a, const Item b, const Item c) const { Item max = a ; if (max < b) max = b ; if (max < c) max = c ; return max ; } Node * IntervalTree :: m_MakeNode (void) const { Node * newNode = new Node ; if (newNode) { newNode -> min = m_min ; newNode -> max = m_max ; newNode -> maxOfAll = m_max ; newNode -> number = m_number ; newNode -> left = newNode -> right = NULL ; } return newNode ; } Node * IntervalTree :: m_Updata (Node * const pn) const { Item leftMax, rightMax ; leftMax = rightMax = NEGATIVE_INFINITY ; if (pn -> left) leftMax = pn -> left -> maxOfAll ; if (pn -> right) rightMax = pn -> right -> maxOfAll ; pn -> maxOfAll = m_Max (leftMax, rightMax, pn -> max) ; return pn ; } Node * IntervalTree :: m_Insert (Node * pn) { if (pn) { if (m_min < pn -> min) pn -> left = m_Insert (pn -> left) ; else pn -> right = m_Insert (pn -> right) ; if (false == m_outOfSpace) pn = m_Updata (pn) ; } else { pn = m_MakeNode () ; if (!pn) m_outOfSpace = true ; } return pn ; } Node * IntervalTree :: m_Delete (Node * pn) { if (pn) { if (m_min < pn -> min) pn -> left = m_Delete (pn -> left) ; else if (m_min > pn -> min) pn -> right = m_Delete (pn -> right) ; else { if (m_max == pn -> max) { if (pn -> left && pn -> right) { m_FindNewMinAndMax (pn -> right) ; pn -> min = m_min ; pn -> max = m_max ; pn -> right = m_Delete (pn -> right) ; } else if (pn -> left) { Node * temp = pn ; pn = pn -> left ; delete temp ; } else { Node * temp = pn ; pn = pn -> right ; delete temp ; } } else pn -> right = m_Delete (pn -> right) ; } if (true == m_hasDiscovered && pn) pn = m_Updata (pn) ; } else m_hasDiscovered = false ; return pn ; } Node * IntervalTree :: m_Search (Node * pn) const { Node * pMinMin ; if (pn) { if (pn -> left && pn -> left -> maxOfAll >= m_min) { pMinMin = m_Search (pn -> left) ; if (pMinMin) return pMinMin ; else if (m_Overlap (pn -> min, pn -> max)) return pn ; else return NULL ; } else if (m_Overlap (pn -> min, pn -> max)) return pn ; else return m_Search (pn -> right) ; } else return NULL ; } int IntervalTree :: m_SearchAll (const Node * const pn) { static int count = 0 ; if (pn) { if (pn -> left && m_min <= pn -> left -> maxOfAll) m_SearchAll (pn -> left) ; if (m_Overlap (pn -> min, pn -> max)) { std :: cout << "No." << pn -> number << std :: endl ; ++count ; } if (pn -> right && m_min <= pn -> right -> maxOfAll) m_SearchAll (pn -> right) ; } return count ; } void IntervalTree :: m_FindNewMinAndMax (const Node * pn) { while (pn -> left) pn = pn -> left ; m_min = pn -> min ; m_max = pn -> max ; } void IntervalTree :: m_Release (const Node * const pn) const { if (pn) { m_Release (pn -> left) ; m_Release (pn -> right) ; delete pn ; } } void IntervalTree :: m_InOrderTraversal (const Node * const pn) const { if (pn) { m_InOrderTraversal (pn -> left) ; std :: cout << "(" << pn -> min << ", " << pn -> max << ") Max: " << pn -> maxOfAll << std :: endl ; m_InOrderTraversal (pn -> right) ; } } // public: IntervalTree :: IntervalTree (void) { m_root = NULL ; m_outOfSpace = false ; m_hasDiscovered = true ; } bool IntervalTree :: Insert (const Item min, const Item max, const int number) { m_min = min ; m_max = max ; m_number = number ; m_root = m_Insert (m_root) ; if (true == m_outOfSpace) { m_outOfSpace = false ; return false ; } else return true ; } bool IntervalTree :: Delete (const Item min, const Item max) { m_min = min ; m_max = max ; m_root = m_Delete (m_root) ; if (false == m_hasDiscovered) { m_hasDiscovered = true ; return false ; } else return true ; } Node * IntervalTree :: Search (const Item min, const Item max) { m_min = min ; m_max = max ; return m_Search (m_root) ; } int IntervalTree :: SearchAll (const Item min, const Item max) { m_min = min ; m_max = max ; return m_SearchAll (m_root) ; } void IntervalTree :: InOrderTraversal (void) const { m_InOrderTraversal (m_root) ; } IntervalTree :: ~IntervalTree (void) { m_Release (m_root) ; } }