Interval Tree added

This commit is contained in:
IlyaShurupov 2024-02-13 00:18:52 +03:00 committed by Ilya Shurupov
parent 8955a02d05
commit 782a041ba8
6 changed files with 311 additions and 4 deletions

View 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);
}
};
}

View file

@ -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: