📄 collect.cxx
字号:
PINDEX PAbstractList::GetObjectsIndex(const PObject * obj) const{ PINDEX index = 0; Element * element = info->head; while (element != NULL) { if (element->data == obj) { info->lastElement = element; info->lastIndex = index; return index; } element = element->next; index++; } return P_MAX_INDEX;}PINDEX PAbstractList::GetValuesIndex(const PObject & obj) const{ PINDEX index = 0; Element * element = info->head; while (element != NULL) { if (*element->data == obj) { info->lastElement = element; info->lastIndex = index; return index; } element = element->next; index++; } return P_MAX_INDEX;}BOOL PAbstractList::SetCurrent(PINDEX index) const{ if (index >= GetSize()) return FALSE; if (info->lastElement == NULL || info->lastIndex >= GetSize() || index < info->lastIndex/2 || index > (info->lastIndex+GetSize())/2) { if (index < GetSize()/2) { info->lastIndex = 0; info->lastElement = info->head; } else { info->lastIndex = GetSize()-1; info->lastElement = info->tail; } } while (info->lastIndex < index) { info->lastElement = info->lastElement->next; info->lastIndex++; } while (info->lastIndex > index) { info->lastElement = info->lastElement->prev; info->lastIndex--; } return TRUE;}PAbstractList::Element::Element(PObject * theData){ next = prev = NULL; data = theData;}///////////////////////////////////////////////////////////////////////////////PAbstractSortedList::Element nil = NULL;PAbstractSortedList::PAbstractSortedList(){ info = new Info; PAssert(info != NULL, POutOfMemory);}void PAbstractSortedList::DestroyContents(){ RemoveAll(); delete info;}void PAbstractSortedList::CopyContents(const PAbstractSortedList & list){ info = list.info;}void PAbstractSortedList::CloneContents(const PAbstractSortedList * list){ Element * element = list->info->root; while (element->left != &nil) element = element->left; info = new Info; PAssertNULL(info); while (element != &nil) { Append(element->data->Clone()); element = element->Successor(); }}BOOL PAbstractSortedList::SetSize(PINDEX){ return TRUE;}PObject::Comparison PAbstractSortedList::Compare(const PObject & obj) const{ PAssert(obj.IsDescendant(PAbstractSortedList::Class()), PInvalidCast); Element * elmt1 = info->root; while (elmt1->left != &nil) elmt1 = elmt1->left; Element * elmt2 = ((const PAbstractSortedList &)obj).info->root; while (elmt2->left != &nil) elmt2 = elmt2->left; while (elmt1 != &nil && elmt2 != &nil) { if (elmt1 == &nil) return LessThan; if (elmt2 == &nil) return GreaterThan; if (*elmt1->data < *elmt2->data) return LessThan; if (*elmt1->data > *elmt2->data) return GreaterThan; elmt1 = elmt1->Successor(); elmt2 = elmt2->Successor(); } return EqualTo;}PINDEX PAbstractSortedList::Append(PObject * obj){ Element * z = new Element(PAssertNULL(obj)); Element * x = info->root; Element * y = &nil; while (x != &nil) { x->subTreeSize++; y = x; x = *z->data < *x->data ? x->left : x->right; } z->parent = y; if (y == &nil) info->root = z; else if (*z->data < *y->data) y->left = z; else y->right = z; info->lastElement = x = z; x->colour = Element::Red; while (x != info->root && x->parent->colour == Element::Red) { if (x->parent == x->parent->parent->left) { y = x->parent->parent->right; if (y->colour == Element::Red) { x->parent->colour = Element::Black; y->colour = Element::Black; x->parent->parent->colour = Element::Red; x = x->parent->parent; } else { if (x == x->parent->right) { x = x->parent; LeftRotate(x); } x->parent->colour = Element::Black; x->parent->parent->colour = Element::Red; RightRotate(x->parent->parent); } } else { y = x->parent->parent->left; if (y->colour == Element::Red) { x->parent->colour = Element::Black; y->colour = Element::Black; x->parent->parent->colour = Element::Red; x = x->parent->parent; } else { if (x == x->parent->left) { x = x->parent; RightRotate(x); } x->parent->colour = Element::Black; x->parent->parent->colour = Element::Red; LeftRotate(x->parent->parent); } } } info->root->colour = Element::Black; x = info->lastElement; info->lastIndex = x->left->subTreeSize; while (x != info->root) { if (x != x->parent->left) info->lastIndex += x->parent->left->subTreeSize+1; x = x->parent; } reference->size++; return info->lastIndex;}BOOL PAbstractSortedList::Remove(const PObject * obj){ Element * element = info->root; while (element != &nil && element->data != obj) element = *obj < *element->data ? element->left : element->right; if (element == &nil) return FALSE; RemoveElement(element); return TRUE;}PObject * PAbstractSortedList::RemoveAt(PINDEX index){ Element * node = info->root->OrderSelect(index+1); PObject * data = node->data; RemoveElement(node); return reference->deleteObjects ? (PObject *)NULL : data;}void PAbstractSortedList::RemoveAll(){ if (info->root != &nil) { info->root->DeleteSubTrees(reference->deleteObjects); delete info->root; info->root = &nil; reference->size = 0; }}PINDEX PAbstractSortedList::Insert(const PObject &, PObject * obj){ return Append(obj);}PINDEX PAbstractSortedList::InsertAt(PINDEX, PObject * obj){ return Append(obj);}BOOL PAbstractSortedList::SetAt(PINDEX, PObject *){ return FALSE;}PObject * PAbstractSortedList::GetAt(PINDEX index) const{ if (index >= GetSize()) return NULL; if (index != info->lastIndex) { if (index == info->lastIndex-1) { info->lastIndex--; info->lastElement = info->lastElement->Predecessor(); } else if (index == info->lastIndex+1 && info->lastElement != NULL) { info->lastIndex++; info->lastElement = info->lastElement->Successor(); } else { info->lastIndex = index; info->lastElement = info->root->OrderSelect(index+1); } } return PAssertNULL(info->lastElement)->data;}PINDEX PAbstractSortedList::GetObjectsIndex(const PObject * obj) const{ Element * elmt = NULL; PINDEX pos = info->root->ValueSelect(*obj, elmt); if (pos == P_MAX_INDEX) return P_MAX_INDEX; if (elmt->data != obj) { PINDEX savePos = pos; Element * saveElmt = elmt; while (elmt->data != obj && (elmt = elmt->Predecessor()) != &nil && *obj == *elmt->data) pos--; if (elmt->data != obj) { pos = savePos; elmt = saveElmt; while (elmt->data != obj && (elmt = elmt->Successor()) != &nil && *obj == *elmt->data) pos++; if (elmt->data != obj) return P_MAX_INDEX; } } info->lastIndex = pos; info->lastElement = elmt; return pos;}PINDEX PAbstractSortedList::GetValuesIndex(const PObject & obj) const{ PINDEX pos = info->root->ValueSelect(obj, info->lastElement); if (pos == P_MAX_INDEX) return P_MAX_INDEX; info->lastIndex = pos; Element * prev; while ((prev = info->lastElement->Predecessor()) != &nil && obj == *prev->data) { info->lastElement = prev; info->lastIndex--; } return info->lastIndex;}void PAbstractSortedList::RemoveElement(Element * node){ PAssertNULL(node); if (node->data != NULL && reference->deleteObjects) delete node->data; Element * y = node->left == &nil || node->right == &nil ? node : node->Successor(); Element * t = y; while (t != &nil) { t->subTreeSize--; t = t->parent; } Element * x = y->left != &nil ? y->left : y->right; x->parent = y->parent; if (y->parent == &nil) info->root = x; else if (y == y->parent->left) y->parent->left = x; else y->parent->right = x; if (y != node) node->data = y->data; if (y->colour == Element::Black) { while (x != info->root && x->colour == Element::Black) { if (x == x->parent->left) { Element * w = x->parent->right; if (w->colour == Element::Red) { w->colour = Element::Black; x->parent->colour = Element::Red; LeftRotate(x->parent); w = x->parent->right; } if (w->left->colour == Element::Black && w->right->colour == Element::Black) { w->colour = Element::Red; x = x->parent; } else { if (w->right->colour == Element::Black) { w->left->colour = Element::Black; w->colour = Element::Red; RightRotate(w); w = x->parent->right; } w->colour = x->parent->colour; x->parent->colour = Element::Black; w->right->colour = Element::Black; LeftRotate(x->parent); x = info->root; } } else { Element * w = x->parent->left; if (w->colour == Element::Red) { w->colour = Element::Black; x->parent->colour = Element::Red; RightRotate(x->parent); w = x->parent->left; } if (w->right->colour == Element::Black && w->left->colour == Element::Black) { w->colour = Element::Red; x = x->parent; } else { if (w->left->colour == Element::Black) { w->right->colour = Element::Black; w->colour = Element::Red; LeftRotate(w); w = x->parent->left; } w->colour = x->parent->colour; x->parent->colour = Element::Black; w->left->colour = Element::Black; RightRotate(x->parent); x = info->root; } } } x->colour = Element::Black; } delete y; reference->size--; info->lastIndex = P_MAX_INDEX; info->lastElement = NULL;}void PAbstractSortedList::LeftRotate(Element * node){ Element * pivot = PAssertNULL(node)->right; node->right = pivot->left; if (pivot->left != &nil) pivot->left->parent = node; pivot->parent = node->parent; if (node->parent == &nil) info->root = pivot; else if (node == node->parent->left) node->parent->left = pivot; else node->parent->right = pivot; pivot->left = node; node->parent = pivot; pivot->subTreeSize = node->subTreeSize; node->subTreeSize = node->left->subTreeSize + node->right->subTreeSize + 1;}void PAbstractSortedList::RightRotate(Element * node){ Element * pivot = PAssertNULL(node)->left; node->left = pivot->right; if (pivot->right != &nil) pivot->right->parent = node; pivot->parent = node->parent; if (node->parent == &nil) info->root = pivot; else if (node == node->parent->right) node->parent->right = pivot; else node->parent->left = pivot; pivot->right = node; node->parent = pivot; pivot->subTreeSize = node->subTreeSize; node->subTreeSize = node->left->subTreeSize + node->right->subTreeSize + 1;}PAbstractSortedList::Element::Element(PObject * theData){ parent = left = right = &nil; colour = Black; subTreeSize = theData != NULL ? 1 : 0; data = theData;}PAbstractSortedList::Element * PAbstractSortedList::Element::Successor() const{ Element * next; if (right != &nil) { next = right; while (next->left != &nil) next = next->left; } else { next = parent; const Element * node = this; while (next != &nil && node == next->right) { node = next; next = node->parent; } } return next;}PAbstractSortedList::Element*PAbstractSortedList::Element::Predecessor() const{ Element * pred; if (left != &nil) { pred = left; while (pred->right != &nil) pred = pred->right; } else { pred = parent; const Element * node = this; while (pred != &nil && node == pred->left) { node = pred; pred = node->parent; } } return pred;}PAbstractSortedList::Element * PAbstractSortedList::Element::OrderSelect(PINDEX index){ PINDEX r = left->subTreeSize+1; if (index == r) return this; if (index < r) { if (left != &nil) return left->OrderSelect(index); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -