file name: duplist.hpp, duplist.cpp
classification: simulation
contents: class ACSortedArray
use: a list class that stores pointers to arbitrary objects
with a sort key of type double; it is optimized for sequential access but
will perform binary search if necessary; the list can handle duplicate
entries
global items used:
member types:
class CArrayElement:
stores a pointer to the data and the key (type double).
member variables:
INT32 allocSize_:
the number of additional elements that are allocated if the array is expanded.
default: parameter aSize of the ctor
CArrayElement
*array_: a pointer to the beginning of the sorted array. Every entry
is stored in an object of type CArrayElement.
default and reset value: a newly created array with allocSize
elements.
INT32 current_:
contains the index of the currently accessed entry. That may also be a
free entry (in that case, the current pointer is said to be invalid).
default and reset value: 0
EBool duplicates_:
is True if duplicate entries are allowed, False if no two keys may have
the same value.
default: parameter duplicates of the ctor
INT32 firstFree_:
contains the index of the first free entry in the array.
default and reset value: 0
INT32 size_:
the current size of the array.
default and reset value: allocSize
member functions:
ACSortedArray
(EBool duplicates = False, INT32 aSize = ArrayAllocationSize): The
data is stored in an array, and aSize is the number of array entries
that are allocated or freed whenever the array is expanded or shrinked.
The ctor allocates an array of storage objects (type CArrayElement)
with that number of entries. allocSize stores the aSize
value. If duplicates is True, duplicate entries are allowed. If
it is False, the object keys must be unique.
virtual
~ACSortedArray (): destructor, pure virtual
Since a destructor is always called, even if it is pure virtual, the
array that is created in the ctor is deleted here. Deleting the array deletes
the storage objects of type CArrayElement, but does not free the
memory used for the data. So all entries should be deleted before the list
class is destroyed.
void
AllocateMemory(): Allocates a new array that is allocSize
elements bigger than the current array. The data is copied to the new array,
and the old array is discarded.
INT32
AllocationSize() const: Returns the additional size used for expansion
or contraction of the array.
EBool BeginOfList
() const: Returns True if the current pointer, which always
contains the index of the data that was accessed last, is at the beginning
of the list, False if it is not at the beginning or if the array is empty.
EBool
CurrentIsValid () const: The function returns True if current
contains the index of an occupied slot, False if it does not.
EBool
Duplicates() const: Returns True if duplicate entries are allowed,
otherwise False.
EBool Empty()
const: returns True if the array is empty, False if objects are stored.
EBool EndOfList
() const: Returns True if the current pointer is at the end
of the list, False if it is not at the end or if the array is empty.
void* Find
(double index): Searches for the first entry with the key index.
If the list is not empty, it first checks if current is valid.
If it is, the element current points to is checked. If the key
does not match the search key, it checks the neighbours of current.
If their keys do not match either, or if current was invalid in
the first place, binary search is used to find an element with the key.
If one is found and duplicate entries are allowed, its predecessors are
checked until the first element with this key is found and the pointer
to its data is returned. If no element with this key is found, NULL is
returned and current contains the index where the element should
be inserted (if the element is to be appended, current is now
invalid!).
void* FindNext
(): If the successor of the current object has the same key as the
current one, its data is returned and the current pointer is set
to its index. The function returns NULL if no duplicates are allowed, if
current does not point to a valid index, if the end of the list has been
reached or if the successor has a different key.
void
FreeMemory(): Allocates a new array that is allocSize elements
smaller than the current array (if that would result in a non-positive
size, an assert fails). The data is copied to the new array, and the old
array is discarded. All data must fit into the new array. If that is not
the case, an assert will fail.
void*
GetCurrent () const: Returns the pointer to the data entry of the
element pointed to by current. current must contain a
valid index, otherwise an assert will fail.
double
GetCurrentID () const: The function returns the key of the element
pointed to by current. current must contain a valid index,
otherwise an assert will fail.
void* GetCurrentObject
() const: Returns a pointer to the data element that is currently
being accessed or NULL, if no element is being accessed (ie. if current
is invalid).
double GetCurrentObjectID
() const: Returns the key of the element that is currently being accessed
or NoAccount if no element is being accessed.
void* GetFirst
(): Returns the pointer to the first data entry in the array, or NULL
if the array is empty. If the list is not empty, current is set
to the index of the first element.
void* GetLast
(): Returns the pointer to the last data entry in the array, or NULL
if the array is empty. If the list is not empty, current is set
to the index of the last element.
void* GetNext
(): If current is valid, ie., if it contains the index of
an array entry that is occupied (data is stored there), the function returns
the pointer of the next data entry in the array. It returns NULL if the
array is empty, if the end of the array is reached or if current
does not point to an occupied slot. If this next element exists, current
is incremented accordingly.
void* GetPrev
(): If current is valid, the function returns the pointer
to the previous data entry in the array. It returns NULL if the array is
empty, if the beginning of the array has been reached or if current
is not valid. If this previous element exists, current is decremented
accordingly.
EBool Insert
(void *object, double index): Inserts a new element into the sorted
array. If the object is NULL, False is returned and nothing happens. Otherwise,
the list is searched for an entry with the given key. If one is found and
duplicates is False, again False is returned. If no element with
this key was found, or if duplicates are allowed, the data pointer and
key are stored in the array (if there are duplicate entries, the new element
is inserted as the first) and True is returned. If the last free entry
in the array was used, a new array with more elements (allocSize
entries more than in last array) is allocated and all entries are copied
from the old array to the new one.
void
InsertAtCurrent (void *object, double index): Inserts the new data
at the array position specified by current. Shifts the rest of
the array one element to the right. If current is not valid or
if the array does not contain any free elements, an assert fails. If the
array is full after the new data is inserted, a bigger array is allocated
(using AllocateMemory()).
INT32
Occupied() const: Returns the number of array elements that are currently
in use.
void* Remove
(double index): Removes the data entry with the given key, ie., it
searches for the element, and if the element is found, the array slot is
freed and the pointer to the data entry is returned. If duplicates are
allowed, the first object in the array with the appropriate index will
be removed. If index is NULL or if the data was not found, NULL
is returned. If more than allocSize+1 entries are free, a new
array with fewer entries (allocSize entries less than in last
array) is allocated and all entries are copied from the old array to the
new one.
void
RemoveAtCurrent (): The element pointed to by current is
freed, ie., its key is deleted and all elements after the current one are
shifted one place to the left. Store the data pointer before calling this
function, or it will be lost! If current is no valid index, an
assert fails. If more than allocSize+1 elements are unused, a smaller array
is allocated using FreeMemory().
INT32
Size() const: Returns the current size of the array (ie., the number
of array elements).
void
UpdateArray(): Allocates a new array (the new size is taken from the
private member size) and copies the occupied part of the old array
to the new one. The old array is deleted, and the internal array pointer
is set to the new array. Note that the pointer is set to the new array
*after* the old array has been deleted, so concurrent access should not
be allowed. The new array must be big enough to hold the occupied part
of the old array, otherwise an assert will fail.