📄 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 + -