/* -*- mode: c; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /********************************************************************* * Clustal Omega - Multiple sequence alignment * * Copyright (C) 2010 University College Dublin * * Clustal-Omega is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This file is part of Clustal-Omega. * ********************************************************************/ /* * RCS $Id: list.h 143 2010-10-14 13:11:14Z andreas $ */ // list.h ////////////////////////////////////////////////////////////////////////////// // Double-linked list implementation with head and tail dummy elements // We set head->prev=head and tail->next=tail. // This makes sure that repeated current=current->next; ends up in tail // and repeated current=current->prev; ends up in head. // head and tail optionally contain a NULL element of Typ defined by method Null(Typ) ////////////////////////////////////////////////////////////////////////////// template class List { protected: template class ListEl //elements of List; essentially a data structure { public: Typ1 data; //Typ is type of data to be stored in list ListEl* prev; //points to previous list element ListEl* next; //points to next list element ListEl() : prev(0), next(0) {} ListEl(Typ1 d) : data(d), prev(0), next(0) {} ListEl(ListEl* p, ListEl* n) : prev(p), next(n) {} ListEl(Typ1 d, ListEl* p, ListEl* n) : data(d), prev(p), next(n) {} }; ListEl* head; //points to dummy element at beginning of list ListEl* tail; //points to dummy element at end of list ListEl* current; //current element position within list int size; //Number of elements in list // Use QUICKSORT to sort list in asscending order between two list elements void SortList(ListEl*, ListEl*, int); // Use QUICKSORT to sort list of pointers by comparing elements they point to void SortPointerList(ListEl*, ListEl*); // Swap two list elements by making a flat copy (don't need two copies of data) // Warning: Gets slow if Typ is composite type with many variables (>=5) void SwapContent(ListEl* e1, ListEl* e2) { Typ d; if (e1!=e2) {d=e1->data; e1->data=e2->data; e2->data=d;} } public: ////////////////////////////////////////////////////////////////////////////// // General methods List(); List(Typ d); ~List(); List& operator=(List&); // Set Null element that will be returned when trying to read from an empty list void Null(Typ null) {head->data = tail->data = null;} ////////////////////////////////////////////////////////////////////////////// // Methods that act at the end of the list // Insert Element after LAST element of list (and return address of data element) Typ* Push(Typ); // Remove and return LAST element of list. Returns head->data if list empty Typ Pop(); // return LAST element of list. Returns null element in head->data if list empty Typ ReadLast() {return tail->prev->data;} ////////////////////////////////////////////////////////////////////////////// // Methods that act at the beginning of the list // Insert element as FIRST element of list (and return address of data element) Typ* Enqueue(Typ); // Remove and return element at BEGINNING of list. Returns head->data if list empty Typ Dequeue(); // return FIRST element of list. Returns null element in head->data if list empty Typ ReadFirst() {if (size) return head->next->data; else return head->data;} ////////////////////////////////////////////////////////////////////////////// // Methods that work with 'current' position in the list // Advances current position by 1 and reads next element; returns head->data if at end of list. Typ ReadNext(); // Reads current element again Typ ReadCurrent(); // Moves current position back by 1 and reads previous element; returns head->data if at beginning of list. Typ ReadPrevious(); // Advances current position by 1 and reads address of next element; returns NULL if at end of list. Typ* ReadNextAddress(); // Reads address of current element again, returns NULL if at end of list Typ* ReadCurrentAddress(); // Sets current position to k and reads k'th element (first=1). Returns head->data if current points to no data element Typ Read(int); // Inserts element AFTER CURRENT element; current element will be set to inserted element void Insert(Typ); // Removes and returns element at CURRENT position. New position is one BEFORE current position. // Returns head->data if current points to no data element. After Reset() delete first element (not 0'th) Typ Delete(); // Overwrites data at current position with new data void Overwrite(Typ d) {current->data=d;} // Reset current position to 0 (one BEFORE the first) int Reset() {current = head; return size;} // Reset current position to End (one AFTER the last) int SetToEnd() {current = tail; return size;} ////////////////////////////////////////////////////////////////////////////// // Methods that return information about the list // Return number of list elements (size>=0) int Size() {return size;} // return true if end of list, i.e. ReadNext would give tail->data (i.e. current position >= Size) char End() {return (current==tail || current==tail->prev);} char End(void* curr) {return ( curr == tail || curr == tail->prev);} // return true if start of list, i.e. ReadPrevious would give head->data (i.e. current position <=1) char Start() {return (current==head || current==head->next);} // Get current position within list (0 <= pos <= Size+1) int GetPos(); //print out list (elements assumed int) void PrintList(); // Get largest data element (Null element for empty list) Typ Largest(); // Get smallest data element (Null element for empty list) Typ Smallest(); ////////////////////////////////////////////////////////////////////////////// // Methods that manipulate the list as a whole // Reverse list void Reverse(); // Copies list into list object void Copy(List* list); // Appends a copy of list to class object void AppendCopy(List* list); // Appends list to class object list void Append(List* list); // Use QUICKSORT to sort list in ascending order. Use only for UNSORTED lists, otherwise time O(N^2) instead of O(N*log(N)) /* void SortList() {if (size>1) SortList(head->next, tail->prev);} */ void SortList() {if (size>1) SortList(head->next, tail->prev, size);} void QuickSort() {if (size>1) SortList(head->next, tail->prev, size);} // Use QUICKSORT to sort list of pointers in ascending order. Use only for UNSORTED lists, otherwwise time O(N^2)! void SortPointerList() {if (size>1) SortPointerList(head->next, tail->prev);} void QuickSortPointer() {if (size>1) SortPointerList(head->next, tail->prev);} // Use INSERTSORT to sort list in asscending order. Use only for PRESORTED lists, otherwise time O(N^2)! void ResortList(); };