TArray Binary Search

This commit is contained in:
Ricardo Luís Vaz Silva 2024-02-13 16:44:10 -03:00 committed by Rachael Alexanderson
parent b2cb4b0a6d
commit cc51b486e0

View file

@ -355,6 +355,105 @@ public:
return i; return i;
} }
// !!! THIS REQUIRES AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
bool IsSorted()
{
for(unsigned i = 1; i < Count; i++)
{
if(Array[i] < Array[i-1]) return false;
}
return true;
}
template<typename Func>
bool IsSorted(Func lt)
{
for(unsigned i = 1; i < Count; i++)
{
if(lt(Array[i], Array[i-1])) return false;
}
return true;
}
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
// !!! AND AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
//
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
unsigned int SortedFind(const T& item, bool exact = true) const
{
if(Count == 0) return 0;
if(Count == 1) return (item < Array[0]) ? 0 : 1;
unsigned int lo = 0;
unsigned int hi = Count - 1;
while(lo <= hi)
{
int mid = lo + ((hi - lo) / 2);
if(Array[mid] < item)
{
lo = mid + 1;
}
else if(item < Array[mid])
{
hi = mid - 1;
}
else
{
return mid;
}
}
if(exact)
{
return Count;
}
else
{
return (lo == Count || (item < Array[lo])) ? lo : lo + 1;
}
}
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
//
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
template<typename Func>
unsigned int SortedFind(const T& item, Func lt, bool exact = true) const
{
if(Count == 0) return 0;
if(Count == 1) return lt(item, Array[0]) ? 0 : 1;
unsigned int lo = 0;
unsigned int hi = Count - 1;
while(lo <= hi)
{
int mid = lo + ((hi - lo) / 2);
if(lt(Array[mid], item))
{
lo = mid + 1;
}
else if(lt(item, Array[mid]))
{
if(mid == 0) break; // prevent negative overflow due to unsigned numbers
hi = mid - 1;
}
else
{
return mid;
}
}
if(exact)
{
return Count;
}
else
{
return (lo == Count || lt(item, Array[lo])) ? lo : lo + 1;
}
}
bool Contains(const T& item) const bool Contains(const T& item) const
{ {
unsigned int i; unsigned int i;
@ -462,6 +561,21 @@ public:
return f; return f;
} }
unsigned SortedAddUnique(const T& obj)
{
auto f = SortedFind(obj, true);
if (f == Size()) Push(obj);
return f;
}
template<typename Func>
unsigned SortedAddUnique(const T& obj, Func lt)
{
auto f = SortedFind(obj, lt, true);
if (f == Size()) Push(obj);
return f;
}
bool Pop () bool Pop ()
{ {
if (Count > 0) if (Count > 0)
@ -542,6 +656,17 @@ public:
} }
} }
void SortedInsert (const T &item)
{
Insert (SortedFind (item, false), item);
}
template<typename Func>
void SortedInsert (const T &item, Func lt)
{
Insert (SortedFind (item, lt, false), item);
}
void ShrinkToFit () void ShrinkToFit ()
{ {
if (Most > Count) if (Most > Count)