📄 collect.cxx
字号:
if (right != &nil)
return right->OrderSelect(index - r);
}
PAssertAlways("Order select failed!");
return &nil;
}
PINDEX PAbstractSortedList::Element::ValueSelect(const PObject & obj,
Element * & lastElement)
{
if (this != &nil) {
switch (data->Compare(obj)) {
case PObject::LessThan :
{
PINDEX index = right->ValueSelect(obj, lastElement);
if (index != P_MAX_INDEX)
return left->subTreeSize + index + 1;
break;
}
case PObject::GreaterThan :
return left->ValueSelect(obj, lastElement);
default :
lastElement = this;
return left->subTreeSize;
}
}
return P_MAX_INDEX;
}
void PAbstractSortedList::Element::DeleteSubTrees(BOOL deleteObject)
{
if (left != &nil) {
left->DeleteSubTrees(deleteObject);
delete left;
left = &nil;
}
if (right != &nil) {
right->DeleteSubTrees(deleteObject);
delete right;
right = &nil;
}
if (deleteObject) {
delete data;
data = NULL;
}
}
PAbstractSortedList::Info::Info()
{
root = &nil;
lastElement = NULL;
lastIndex = P_MAX_INDEX;
}
///////////////////////////////////////////////////////////////////////////////
PObject * POrdinalKey::Clone() const
{
return new POrdinalKey(theKey);
}
PObject::Comparison POrdinalKey::Compare(const PObject & obj) const
{
PAssert(obj.IsDescendant(POrdinalKey::Class()), PInvalidCast);
const POrdinalKey & other = (const POrdinalKey &)obj;
if (theKey < other.theKey)
return LessThan;
if (theKey > other.theKey)
return GreaterThan;
return EqualTo;
}
PINDEX POrdinalKey::HashFunction() const
{
return PABSINDEX(theKey)%23;
}
void POrdinalKey::PrintOn(ostream & strm) const
{
strm << theKey;
}
///////////////////////////////////////////////////////////////////////////////
void PHashTable::Table::DestroyContents()
{
for (PINDEX i = 0; i < GetSize(); i++) {
Element * list = GetAt(i);
if (list != NULL) {
Element * elmt = list;
do {
Element * nextElmt = elmt->next;
if (elmt->data != NULL && reference->deleteObjects)
delete elmt->data;
if (deleteKeys)
delete elmt->key;
delete elmt;
elmt = nextElmt;
} while (elmt != list);
}
}
PAbstractArray::DestroyContents();
}
PINDEX PHashTable::Table::AppendElement(PObject * key, PObject * data)
{
lastElement = NULL;
PINDEX bucket = PAssertNULL(key)->HashFunction();
Element * list = GetAt(bucket);
Element * element = new Element;
PAssertNULL(element);
element->key = key;
element->data = data;
if (list == NULL) {
element->next = element->prev = element;
SetAt(bucket, element);
}
else if (list == list->prev) {
list->next = list->prev = element;
element->next = element->prev = list;
}
else {
element->next = list;
element->prev = list->prev;
list->prev->next = element;
list->prev = element;
}
lastElement = element;
lastIndex = P_MAX_INDEX;
return bucket;
}
PObject * PHashTable::Table::RemoveElement(const PObject & key)
{
PObject * obj = NULL;
if (GetElementAt(key) != NULL) {
if (lastElement == lastElement->prev)
SetAt(key.HashFunction(), NULL);
else {
lastElement->prev->next = lastElement->next;
lastElement->next->prev = lastElement->prev;
SetAt(key.HashFunction(), lastElement->next);
}
obj = lastElement->data;
if (deleteKeys)
delete lastElement->key;
delete lastElement;
lastElement = NULL;
}
return obj;
}
BOOL PHashTable::Table::SetLastElementAt(PINDEX index)
{
if (index == 0 || lastElement == NULL || lastIndex == P_MAX_INDEX) {
lastIndex = 0;
lastBucket = 0;
while ((lastElement = GetAt(lastBucket)) == NULL) {
if (lastBucket >= GetSize())
return FALSE;
lastBucket++;
}
}
if (lastIndex == index)
return TRUE;
if (lastIndex < index) {
while (lastIndex != index) {
if (lastElement->next != operator[](lastBucket))
lastElement = lastElement->next;
else {
do {
if (++lastBucket >= GetSize())
return FALSE;
} while ((lastElement = operator[](lastBucket)) == NULL);
}
lastIndex++;
}
}
else {
while (lastIndex != index) {
if (lastElement != operator[](lastBucket))
lastElement = lastElement->prev;
else {
do {
if (lastBucket-- == 0)
return FALSE;
} while ((lastElement = operator[](lastBucket)) == NULL);
lastElement = lastElement->prev;
}
lastIndex--;
}
}
return TRUE;
}
PHashTable::Element * PHashTable::Table::GetElementAt(const PObject & key)
{
if (lastElement != NULL && *lastElement->key == key)
return lastElement;
Element * list = GetAt(key.HashFunction());
if (list != NULL) {
Element * element = list;
do {
if (*element->key == key) {
lastElement = element;
lastIndex = P_MAX_INDEX;
return lastElement;
}
element = element->next;
} while (element != list);
}
return NULL;
}
PINDEX PHashTable::Table::GetElementsIndex(
const PObject * obj, BOOL byValue, BOOL keys) const
{
PINDEX index = 0;
for (PINDEX i = 0; i < GetSize(); i++) {
Element * list = operator[](i);
if (list != NULL) {
Element * element = list;
do {
PObject * keydata = keys ? element->key : element->data;
if (byValue ? (*keydata == *obj) : (keydata == obj))
return index;
element = element->next;
index++;
} while (element != list);
}
}
return P_MAX_INDEX;
}
///////////////////////////////////////////////////////////////////////////////
PHashTable::PHashTable()
: hashTable(new PHashTable::Table)
{
PAssertNULL(hashTable);
hashTable->lastElement = NULL;
}
void PHashTable::DestroyContents()
{
hashTable->reference->deleteObjects = reference->deleteObjects;
delete hashTable;
}
void PHashTable::CopyContents(const PHashTable & hash)
{
hashTable = hash.hashTable;
}
void PHashTable::CloneContents(const PHashTable * hash)
{
PAssertNULL(hash);
PINDEX sz = hash->GetSize();
PAssertNULL(hash->hashTable);
PHashTable::Table * original = hash->hashTable;
hashTable = new PHashTable::Table(original->GetSize());
PAssertNULL(hashTable);
hashTable->lastElement = NULL;
for (PINDEX i = 0; i < sz; i++) {
original->SetLastElementAt(i);
PObject * data = original->lastElement->data;
if (data != NULL)
data = data->Clone();
hashTable->AppendElement(original->lastElement->key->Clone(), data);
}
}
PObject::Comparison PHashTable::Compare(const PObject & obj) const
{
PAssert(obj.IsDescendant(PHashTable::Class()), PInvalidCast);
return reference != ((const PHashTable &)obj).reference
? GreaterThan : EqualTo;
}
BOOL PHashTable::SetSize(PINDEX)
{
return TRUE;
}
PObject & PHashTable::AbstractGetDataAt(PINDEX index) const
{
PAssert(hashTable->SetLastElementAt(index), PInvalidArrayIndex);
return *hashTable->lastElement->data;
}
const PObject & PHashTable::AbstractGetKeyAt(PINDEX index) const
{
PAssert(hashTable->SetLastElementAt(index), PInvalidArrayIndex);
return *hashTable->lastElement->key;
}
///////////////////////////////////////////////////////////////////////////////
void PAbstractSet::DestroyContents()
{
hashTable->deleteKeys = reference->deleteObjects;
PHashTable::DestroyContents();
}
void PAbstractSet::CopyContents(const PAbstractSet & )
{
}
void PAbstractSet::CloneContents(const PAbstractSet * )
{
}
PINDEX PAbstractSet::Append(PObject * obj)
{
if (AbstractContains(*obj)) {
if (reference->deleteObjects)
delete obj;
return P_MAX_INDEX;
}
reference->size++;
return hashTable->AppendElement(obj, NULL);
}
PINDEX PAbstractSet::Insert(const PObject &, PObject * obj)
{
return Append(obj);
}
PINDEX PAbstractSet::InsertAt(PINDEX, PObject * obj)
{
return Append(obj);
}
BOOL PAbstractSet::Remove(const PObject * obj)
{
if (hashTable->GetElementAt(*PAssertNULL(obj)) == NULL)
return FALSE;
hashTable->deleteKeys = hashTable->reference->deleteObjects = reference->deleteObjects;
hashTable->RemoveElement(*obj);
reference->size--;
return TRUE;
}
PObject * PAbstractSet::RemoveAt(PINDEX index)
{
if (!hashTable->SetLastElementAt(index))
return NULL;
PObject * obj = hashTable->lastElement->key;
hashTable->deleteKeys = hashTable->reference->deleteObjects = reference->deleteObjects;
hashTable->RemoveElement(*obj);
reference->size--;
return obj;
}
PINDEX PAbstractSet::GetObjectsIndex(const PObject * obj) const
{
return hashTable->GetElementsIndex(obj, FALSE, TRUE);
}
PINDEX PAbstractSet::GetValuesIndex(const PObject & obj) const
{
return hashTable->GetElementsIndex(&obj, TRUE, TRUE);
}
PObject * PAbstractSet::GetAt(PINDEX index) const
{
return (PObject *)&AbstractGetKeyAt(index);
}
BOOL PAbstractSet::SetAt(PINDEX, PObject * obj)
{
return Append(obj);
}
///////////////////////////////////////////////////////////////////////////////
PINDEX PAbstractDictionary::Append(PObject *)
{
PAssertAlways(PUnimplementedFunction);
return 0;
}
PINDEX PAbstractDictionary::Insert(const PObject & before, PObject * obj)
{
AbstractSetAt(before, obj);
return 0;
}
PINDEX PAbstractDictionary::InsertAt(PINDEX index, PObject * obj)
{
AbstractSetAt(AbstractGetKeyAt(index), obj);
return index;
}
BOOL PAbstractDictionary::Remove(const PObject *)
{
PAssertAlways(PUnimplementedFunction);
return FALSE;
}
PObject * PAbstractDictionary::RemoveAt(PINDEX index)
{
PObject & obj = AbstractGetDataAt(index);
AbstractSetAt(AbstractGetKeyAt(index), NULL);
return &obj;
}
PINDEX PAbstractDictionary::GetObjectsIndex(const PObject * obj) const
{
return hashTable->GetElementsIndex(obj, FALSE, FALSE);
}
PINDEX PAbstractDictionary::GetValuesIndex(const PObject & obj) const
{
return hashTable->GetElementsIndex(&obj, TRUE, FALSE);
}
BOOL PAbstractDictionary::SetAt(PINDEX index, PObject * val)
{
return AbstractSetAt(POrdinalKey(index), val);
}
PObject * PAbstractDictionary::GetAt(PINDEX index) const
{
return AbstractGetAt(POrdinalKey(index));
}
BOOL PAbstractDictionary::SetDataAt(PINDEX index, PObject * val)
{
return AbstractSetAt(AbstractGetKeyAt(index), val);
}
BOOL PAbstractDictionary::AbstractSetAt(const PObject & key, PObject * obj)
{
if (obj == NULL) {
obj = hashTable->RemoveElement(key);
if (obj != NULL) {
if (reference->deleteObjects)
delete obj;
reference->size--;
}
}
else {
Element * element = hashTable->GetElementAt(key);
if (element == NULL) {
hashTable->AppendElement(key.Clone(), obj);
reference->size++;
}
else {
if (reference->deleteObjects)
delete hashTable->lastElement->data;
hashTable->lastElement->data = obj;
}
}
return TRUE;
}
PObject * PAbstractDictionary::AbstractGetAt(const PObject & key) const
{
Element * element = hashTable->GetElementAt(key);
return element != NULL ? element->data : (PObject *)NULL;
}
PObject & PAbstractDictionary::GetRefAt(const PObject & key) const
{
Element * element = hashTable->GetElementAt(key);
return *PAssertNULL(element)->data;
}
void PAbstractDictionary::PrintOn(ostream &strm) const
{
for (PINDEX i = 0; i < GetSize(); i++)
strm << AbstractGetKeyAt(i) << '=' << AbstractGetDataAt(i) << endl;
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -