Interval Tree added
This commit is contained in:
parent
8955a02d05
commit
782a041ba8
6 changed files with 311 additions and 4 deletions
80
Containers/public/IntervalTree.hpp
Normal file
80
Containers/public/IntervalTree.hpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
#include "Tree.hpp"
|
||||
|
||||
namespace tp {
|
||||
|
||||
template <typename tType>
|
||||
class IntervalKey {
|
||||
public:
|
||||
IntervalKey() = default;
|
||||
|
||||
IntervalKey(tType start, tType end) {
|
||||
mStart = start;
|
||||
mEnd = end;
|
||||
}
|
||||
|
||||
inline bool descentRight(const IntervalKey& in) const { return in.mStart > mStart; }
|
||||
inline bool descentLeft(const IntervalKey& in) const { return in.mStart <= mStart; }
|
||||
inline bool exactNode(const IntervalKey& in) const { return in.mStart == mStart && in.mEnd == mEnd; }
|
||||
|
||||
inline const IntervalKey& getFindKey() const { return *this; }
|
||||
inline const IntervalKey& keyInRightSubtree(const IntervalKey& in) const { return in; }
|
||||
inline const IntervalKey& keyInLeftSubtree(const IntervalKey& in) const { return in; }
|
||||
|
||||
template <typename tTreeNodeType>
|
||||
inline void updateTreeCacheCallBack(const tTreeNodeType& node) {
|
||||
mMax = 0;
|
||||
if (node.mRight && node.mRight->key.mMax > mMax) mMax = node.mRight->key.mMax;
|
||||
if (node.mLeft && node.mLeft->key.mMax > mMax) mMax = node.mLeft->key.mMax;
|
||||
if (mMax < mEnd) mMax = mEnd;
|
||||
}
|
||||
|
||||
public:
|
||||
tType mStart = tType();
|
||||
tType mEnd = tType();
|
||||
tType mMax = tType();
|
||||
};
|
||||
|
||||
template <typename tType, typename tData>
|
||||
class IntervalTree : public AvlTree<IntervalKey<tType>, tData> {
|
||||
typedef AvlTree<IntervalKey<tType>, tData>::Node Node;
|
||||
|
||||
public:
|
||||
IntervalTree() = default;
|
||||
|
||||
template <typename tFunctor>
|
||||
ualni forEachIntersection(tType start, tType end, tFunctor functor) const {
|
||||
ualni debug = 0;
|
||||
forEachIntersectionUtil(this->head(), start, end, functor, debug);
|
||||
return debug;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename tFunctor>
|
||||
void forEachIntersectionUtil(const Node* node, tType start, tType end, tFunctor functor, ualni& debug) const {
|
||||
if (node == nullptr) return;
|
||||
|
||||
debug++;
|
||||
|
||||
// If 'start' is to the right of the rightmost point of any interval
|
||||
// in this node and all children, there won't be any matches.
|
||||
if (start > node->key.mMax) return;
|
||||
|
||||
// Search left children
|
||||
forEachIntersectionUtil(node->mLeft, start, end, functor, debug);
|
||||
|
||||
// Check this node
|
||||
if (start < node->key.mEnd && end > node->key.mStart) {
|
||||
functor(node->data);
|
||||
}
|
||||
|
||||
// If end is to the left of the start of this interval,
|
||||
// then it can't be in any child to the right.
|
||||
if (end < node->key.mStart) return;
|
||||
|
||||
// Otherwise, search right children
|
||||
forEachIntersectionUtil(node->mRight, start, end, functor, debug);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -21,7 +21,8 @@ namespace tp {
|
|||
inline AvlNumericKey keyInRightSubtree(AvlNumericKey in) const { return in; }
|
||||
inline AvlNumericKey keyInLeftSubtree(AvlNumericKey in) const { return in; }
|
||||
|
||||
inline void updateTreeCacheCallBack() {}
|
||||
template <typename NodeType>
|
||||
inline void updateTreeCacheCallBack(const NodeType&) {}
|
||||
};
|
||||
|
||||
template <typename Key, typename Data, class Allocator = DefaultAllocator>
|
||||
|
|
@ -42,7 +43,7 @@ namespace tp {
|
|||
Data data;
|
||||
Key key;
|
||||
|
||||
private:
|
||||
public:
|
||||
Node* mLeft = nullptr;
|
||||
Node* mRight = nullptr;
|
||||
Node* mParent = nullptr;
|
||||
|
|
@ -57,7 +58,7 @@ namespace tp {
|
|||
inline KeyArg keyInRightSubtree(KeyArg aKey) const { return key.keyInRightSubtree(aKey); }
|
||||
inline KeyArg keyInLeftSubtree(KeyArg aKey) const { return key.keyInLeftSubtree(aKey); }
|
||||
|
||||
inline void updateTreeCacheCallBack() { key.updateTreeCacheCallBack(); }
|
||||
inline void updateTreeCacheCallBack() { key.updateTreeCacheCallBack(*this); }
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue