/**** * * Implementation of list.h. * */ #include #include "list.h" List::List() : first(null), last(null), size(0), enumstate(null) {} List::~List() { ListItem* i; for (i=first; i; i=i->next) { delete i->data; delete i; } } List* List::Put(ListElem* e) { ListItem* newi = new ListItem; newi->data = e; newi->prev = last; if (last) last->next = newi; last = newi; if (! first) { first = newi; enumstate = first; } size++; return this; } ListElem* List::Pull() { ListItem* item = first; ListElem* data; if (size == 0) return 0; if (first == last) { first = last = enumstate = 0; size = 0; data = item->data; /*delete item;*/ return data; } first = enumstate = item->next; first->prev = 0; size--; data = item->data; delete item; return data; } List* List::Push(ListElem* e) { ListItem* newi = new ListItem; newi->data = e; newi->next = first; if (first) first->prev = newi; enumstate = first = newi; if (! last) last = newi; size++; return this; } ListElem* List::Pop() { ListItem* item = last; ListElem* data; if (size == 0) return 0; if (first == last) { first = last = enumstate = 0; size = 0; data = item->data; delete item; return data; } enumstate = first; last = item->prev; last->next = 0; size--; data = item->data; delete item; return data; } List* List::Insert(ListElem* e, int n) { ListItem* newitem = new ListItem, *next; if (n == 0) return Push(e); if (n == size) return Put(e); if (! GetNth(n)) return this; newitem->data = e; newitem->prev = gotitem; newitem->next = (next = gotitem->next); gotitem->next = newitem; if (next) next->prev = newitem; enumstate = newitem; size++; return this; } ListElem* List::GetNth(int n) { ListItem* nexti; if ((n < 1) || (n > size)) { gotitem = null; return 0; } if (n < size/2) { gotitem = first; while(--n) gotitem = gotitem->next; } else { gotitem = last; while(++n <= size) gotitem = gotitem->prev; } enumstate = (nexti = gotitem->next) ? nexti : first; return gotitem->data; } ListElem* List::RemoveNth(int n) { ListItem* item, prev; ListElem* data; if ((size == 0) || (n < 1) || (n > size)) return 0; if (n == 1) return Pull(); if (n == size) return Pop(); if (n < size/2) { item = first; while(--n) item = item->next; } else { item = last; while(++n <= size) item = item->prev; } item->prev->next = item->next; item->next->prev = item->prev; size--; enumstate = (size == 0) ? null : item->next; data = item->data; delete item; return data; } ListElem* List::Find(ListElemKey* k) { ListItem* ip; for (ip=first, curpos=0; ip; ip=ip->next, curpos++) { if (ip->data->Compare(k) == 0) return ip->data; } return 0; } int List::FindPos(ListElemKey* k) { ListItem* ip; for (ip=first, curpos=0; ip; ip=ip->next, curpos++) { if (ip->data->Compare(k) == 0) { return curpos+1; } } return 0; } int List::Len() { return size; } ListElem* List::Enum() { ListItem* item; if ((item = enumstate)) { enumstate = enumstate->next; return item->data; } else { enumstate = first; return 0; } } void List::ResetEnum() { enumstate = first; } /* * Less-than-totally-gross bubble sort algorithm. */ List* List::Sort(bool ascending) { void Swap(ListItem*, ListItem*); int i, j, n = Len(); ListItem *ip, *jp; for (i=1, ip=first; inext) { for (j=n, jp=last->prev; iprev) { if (ascending) { if (jp->data->Compare(jp->next->data) > 0) jp->Swap(jp->next); } else { if (jp->data->Compare(jp->next->data) < 0) jp->Swap(jp->next); } } } return this; } void ListItem::Swap(ListItem* i) { ListElem* temp; temp = this->data; this->data = i->data; i->data = temp; } void List::Print() { ListItem* item; for (item = first; item; item = item->next) item->data->Print(); printf("\n"); } ListElem::ListElem() {} ListElem::~ListElem() {} int ListElem::Compare(ListElem* e) { return 0; } int ListElem::Compare(ListElemKey* k) { return 0; } ListElemKey* ListElem::GetKey() { return null; } void ListElem::Print() { } ListItem::ListItem() : data(null), next(null), prev(null) {} ListItem::~ListItem() {}