/** * Author: Mark Larkin * * Copyright (c) 2007 Des Higgins, Julie Thompson and Toby Gibson. */ /** * Author: Mark Larkin UCD Conway Institute * * This class is to be used as a linked list type container. * The features are as follows: * 1) It allows efficient deletions anywhere. * 2) It also allows efficient random access. * 3) Its maximum size is fixed at creation. * 4) Items can only be added at the end. * 5) when it is destroyed it will delete the structure, but not the elements. * * Limitations: * It returns the ListElements directly, this is not the best way. A better way would be * to return an iterator of some kind, but this would take alot more work. At the moment * it is possible to have 2 LList objects and get an element from one list, and delete * it from another list. But this is ok for the time being. I will fix this later. */ #ifndef RANDOMACCESSLLIST_H #define RANDOMACCESSLLIST_H namespace clustalw { template class ListElement { public: ListElement() { // Do nothing } ListElement(T* e, ListElement* n, ListElement* p, unsigned int _index) { element = e; next = n; prev = p; index = _index; } ~ListElement() { element = 0; next = 0; } unsigned int getIndex(){return index;} T* element; ListElement* next; ListElement* prev; private: unsigned int index; }; template class RandomAccessLList { public: RandomAccessLList(int size) : maxSize(size), numElements(0) { elements = new ListElement*[size]; for(int i = 0; i < size; i++) { elements[i] = 0; } } ~RandomAccessLList() { for(int i = 0; i < maxSize; i++) { if(elements[i] != 0) { delete elements[i]; } } delete [] elements; } unsigned int getNumElements(){return numElements;} void addElementToBack(T* element) { if(numElements < maxSize) { // Add the element elements[numElements] = new ListElement(element, 0, 0, numElements); if(numElements == 0) { // First element elements[numElements]->next = 0; elements[numElements]->prev = 0; firstElementInList = elements[numElements]; numElements++; } else if(numElements > 0) // If it is not the first element { elements[numElements - 1]->next = elements[numElements]; elements[numElements]->prev = elements[numElements - 1]; elements[numElements]->next = 0; numElements++; } } } ListElement* getAt(int index) { if(index >= 0 && index < maxSize) { return elements[index]; } else { cout << "\nCannot get item : " << index << "\n"; return 0; } } ListElement* getFirst() { return firstElementInList; } void removeItem(ListElement* item) { if(item != 0 ) { int index = item->getIndex(); if(elements[index] != 0) { if(item->prev == 0 && item->next == 0) // Last item in the list { firstElementInList = 0; delete item; // Not sure if this is good or not. item = 0; numElements--; } else if(item->prev == 0) // remove First in the list { firstElementInList = item->next; firstElementInList->prev = 0; item->next = 0; delete item; // Not sure if this is good or not. item = 0; numElements--; } else if(item->next == 0) // remove last item { ListElement* prevElem = item->prev; prevElem->next = 0; item->prev = 0; delete item; // Not sure if this is good or not. item = 0; numElements--; } else // remove middle item { ListElement* prevElem = item->prev; ListElement* nextElem = item->next; prevElem->next = nextElem; nextElem->prev = prevElem; item->prev = 0; item->next = 0; delete item; // Not sure if this is good or not. item = 0; numElements--; } elements[index] = 0; } } else { cout << "ERROR: trying to remove item outside the bounds\n"; } } private: ListElement** elements; ListElement* firstElementInList; int maxSize; unsigned int numElements; }; } #endif