📄 collect.cxx
字号:
while (next != &nil && node == next->right) { node = next; next = node->parent; } } return next;}PAbstractSortedList::Element * PAbstractSortedList::Info ::Predecessor(const Element * node) const{ Element * pred; if (node->left != &nil) { pred = node->left; while (pred->right != &nil) pred = pred->right; } else { pred = node->parent; while (pred != &nil && node == pred->left) { node = pred; pred = node->parent; } } return pred;}PAbstractSortedList::Element * PAbstractSortedList::Info::OrderSelect(Element * node, PINDEX index) const{ PINDEX r = node->left->subTreeSize+1; if (index == r) return node; if (index < r) { if (node->left != &nil) return OrderSelect(node->left, index); } else { if (node->right != &nil) return OrderSelect(node->right, index - r); } PAssertAlways2("PAbstractSortedList::Element", "Order select failed!"); return (Element *)&nil;}PINDEX PAbstractSortedList::ValueSelect(const Element * node, const PObject & obj, const Element ** lastElement) const{ if (node != &info->nil) { switch (node->data->Compare(obj)) { case PObject::LessThan : { PINDEX index = ValueSelect(node->right, obj, lastElement); if (index != P_MAX_INDEX) return node->left->subTreeSize + index + 1; break; } case PObject::GreaterThan : return ValueSelect(node->left, obj, lastElement); default : *lastElement = node; return node->left->subTreeSize; } } return P_MAX_INDEX;}void PAbstractSortedList::DeleteSubTrees(Element * node, BOOL deleteObject){ if (node->left != &info->nil) { DeleteSubTrees(node->left, deleteObject); delete node->left; node->left = &info->nil; } if (node->right != &info->nil) { DeleteSubTrees(node->right, deleteObject); delete node->right; node->right = &info->nil; } if (deleteObject) { delete node->data; node->data = NULL; }}///////////////////////////////////////////////////////////////////////////////PObject * POrdinalKey::Clone() const{ return new POrdinalKey(theKey);}PObject::Comparison POrdinalKey::Compare(const PObject & obj) const{ PAssert(PIsDescendant(&obj, POrdinalKey), 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; PAssert(element != NULL, POutOfMemory); 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){ PAssert(hashTable != NULL, POutOfMemory); hashTable->lastElement = NULL;}void PHashTable::DestroyContents(){ if (hashTable != NULL) { hashTable->reference->deleteObjects = reference->deleteObjects; delete hashTable; hashTable = NULL; }}void PHashTable::CopyContents(const PHashTable & hash){ hashTable = hash.hashTable;} void PHashTable::CloneContents(const PHashTable * hash){ PINDEX sz = PAssertNULL(hash)->GetSize(); PHashTable::Table * original = PAssertNULL(hash->hashTable); hashTable = new PHashTable::Table(original->GetSize()); PAssert(hashTable != NULL, POutOfMemory); 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(PIsDescendant(&obj, PHashTable), 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 (PAssertNULL(obj) == NULL) return FALSE; if (hashTable->GetElementAt(*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 * obj){ PINDEX idx = GetObjectsIndex(obj); if (idx == P_MAX_INDEX) return FALSE; RemoveAt(idx); return TRUE;}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(AbstractGetKeyAt(index), val);}PObject * PAbstractDictionary::GetAt(PINDEX index) const{ PAssert(hashTable->SetLastElementAt(index), PInvalidArrayIndex); return hashTable->lastElement->data;} 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) && (hashTable->lastElement->data != obj)) 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{ char separator = strm.fill(); if (separator == ' ') separator = '\n'; for (PINDEX i = 0; i < GetSize(); i++) { if (i > 0) strm << separator; strm << AbstractGetKeyAt(i) << '=' << AbstractGetDataAt(i); } if (separator == '\n') strm << separator;}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -