--- /dev/null
+/* -*- 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-C.h 143 2010-10-14 13:11:14Z andreas $
+ */
+
+// list.C
+// Class for double-linked list
+
+
+
+#ifndef JLIST
+#define JLIST
+
+#ifndef MAIN
+#include <iostream> // cin, cout
+#include <stdlib.h> //
+#include <stdio.h> //
+using std::cout;
+using std::cerr;
+#endif
+
+#include "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)
+////////////////////////////////////////////////////////////////////////////
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Constructors and destructor
+
+////////////////////////////////////////////////////////////////////////////
+// Creates empty List with two dummy elements
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+List<Typ>::List()
+{
+ head=new ListEl<Typ>();
+ if (!head) { cerr<<"Could not create new element\n"; return; }
+ tail=new ListEl<Typ>(head,NULL);
+ if (!tail) { cerr<<"Could not create new element\n"; return; }
+ tail->next = tail;
+ head->prev = head;
+ head->next = tail;
+ current = head;
+ size=0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Creates List with one element
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+List<Typ>::List(Typ d)
+{
+ head=new ListEl<Typ>();
+ if (!head) { cerr<<"Could not create new element\n"; return; }
+ tail=new ListEl<Typ>();
+ if (!tail) { cerr<<"Could not create new element\n"; return; }
+ ListEl<Typ>* el = new ListEl<Typ>(d,head,tail);
+ if (!el) { cerr<<"Could not create new element\n"; return; }
+ head->prev = head;
+ head->next = el;
+ tail->prev = el;
+ tail->next = tail;
+ current = head;
+ size=1;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Destructor deletes List object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+List<Typ>::~List()
+{
+ ListEl<Typ>* n=head->next;
+ while(head!=n)
+ {
+ delete(head); head = NULL;
+ head=n;
+ n=head->next;
+ }
+ delete(head); head = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Flat copy
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+List<Typ>& List<Typ>::operator=(List<Typ>& l)
+{
+ head = l.head;
+ tail = l.tail;
+ current = l.current;
+ size = l.size;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// Reverse order of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::Reverse()
+{
+ ListEl<Typ> *n; // next list element; also for swapping
+ ListEl<Typ> *c; // current element to be sorted in. Everything to the left is already sorted
+ if (Size()<=1) return;
+ for (c=head; c!=tail; c=n)
+ {
+ // Swap prev and next pointers of all list elements
+ n = c->next;
+ c->next = c->prev;
+ c->prev = n;
+ }
+
+ // Swap prev and next pointers of tail
+ tail->next = tail->prev;
+ tail->prev = tail;
+
+ // Swap head an tail
+ n = head;
+ head = tail;
+ tail = n;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that act at the end of the list
+
+////////////////////////////////////////////////////////////////////////////
+// Insert Element after LAST of list (and return address of data element)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ* List<Typ>::Push(Typ d)
+{
+ ListEl<Typ>* t=new ListEl<Typ>(d,tail->prev,tail);
+ if (!t) { cerr<<"Could not create new element\n"; return 0; }
+ tail->prev->next=t;
+ tail->prev = t;
+ size++;
+ return &(t->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Remove and return LAST element of list. Returns head->data if empty
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Pop()
+{
+ if (!size) return head->data;
+ ListEl<Typ>* t=tail->prev;
+ if (current==t) current=tail;
+ Typ d=t->data;
+ t->prev->next=tail;
+ tail->prev=t->prev;
+ delete t; t = NULL;
+ size--;
+ return d;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that act at the beginning of the list
+
+////////////////////////////////////////////////////////////////////////////
+// Insert element as FIRST element of list (and return address of data element)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ* List<Typ>::Enqueue(Typ d)
+{
+ ListEl<Typ>* h = new ListEl<Typ>(d,head,head->next);
+ if (!h) { cerr<<"Could not create new element\n"; return 0; }
+ h->next->prev = h;
+ head->next=h;
+ size++;
+ return &(h->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Remove element at BEGINNING of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Dequeue()
+{
+ if (!size) return head->data;
+ ListEl<Typ>* h=head->next;
+ if (current==h) current=head;
+ Typ d=h->data;
+ h->next->prev=head;
+ head->next=h->next;
+ delete h; h = NULL;
+ size--;
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that work with 'current' position in the list
+
+////////////////////////////////////////////////////////////////////////////
+// Reads next element; advances current position by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+inline Typ List<Typ>::ReadNext()
+{
+ current = current->next;
+ return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads current element again (NULL if nothing read yet)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+inline Typ List<Typ>::ReadCurrent()
+{
+ return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads previous element; moves current position back by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+inline Typ List<Typ>::ReadPrevious()
+{
+ current = current->prev;
+ return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads next element; advances current position by 1
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+inline Typ* List<Typ>::ReadNextAddress()
+{
+ current = current->next;
+ if (current==tail) return NULL;
+ return &(current->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Reads address of current element again, returns NULL if at end of list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+inline Typ* List<Typ>::ReadCurrentAddress()
+{
+ if (current==tail) return NULL;
+ return &(current->data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Sets current position to k and reads k'th element (first=1)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Read(int pos)
+{
+ if (pos>size) {current = tail; return tail->data;}
+ if (pos<=0) {current = head; return head->data;}
+ current = head->next;
+ for (; pos>1; pos--) current = current->next; //If pos==2 do 1 iteration
+ return current->data;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Inserts element d AFTER current element and sets current element to inserted
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::Insert(Typ d)
+{
+ ListEl<Typ>* el = new ListEl<Typ>(d,current,current->next);
+ if (!el) { cerr<<"Could not create new element\n"; return; }
+ (current->next)->prev = el;
+ current->next = el;
+ current=el;
+ size++;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Deletes current element and returns content of deleted element. Current element
+// will be previous one after Delete(). After Reset() delete first element (not 0'th)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Delete()
+{
+ Typ d;
+ ListEl<Typ>* p;
+ if (!size || current==tail) return tail->data;
+ if (current==head) current = head->next; // After Reset() delete first element (not 0'th)
+ (current->prev)->next = current->next;
+ (current->next)->prev = current->prev;
+ d = current->data;
+ p = current->prev;
+ delete current; current = NULL;
+ current = p;
+ size--;
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Methods that return useful information about the list
+
+////////////////////////////////////////////////////////////////////////////
+// Get current position within list (0 <= pos <= Size+1)
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+int List<Typ>::GetPos()
+{
+ int pos=0;
+ ListEl<Typ>* el;
+ for (el = head; el!=current; el=el->next) pos++;
+ return pos;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//print out list
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::PrintList()
+{
+ int j=0;
+ ListEl<Typ>* c=current;
+ Reset();
+ printf("List: ");
+ while (!End())
+ {
+ j++;
+ cout<<j<<" "<<ReadNext()<<" ";
+ if (!(j%10)) cout<<"\n ";
+ }
+ cout<<"\n";
+ current=c;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Get largest data element
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Largest()
+{
+ Typ* result= &((tail->prev)->data);
+ Reset();
+ while (!End())
+ {
+ if (*result<ReadNext()) result=ReadCurrentAddress();
+ }
+ return *result;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Get smallest data element
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+Typ List<Typ>::Smallest()
+{
+ Typ* result= &((tail->prev)->data);
+ Reset();
+ while (!End())
+ {
+ if (ReadNext()<*result) result=ReadCurrentAddress();
+ }
+ return *result;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Methods that manipulate the list as a whole
+
+////////////////////////////////////////////////////////////////////////////
+// Copies list 0 into list object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::Copy(List<Typ>* list)
+{
+ if (list==this) return;
+ while (!End()) Pop(); //empty list
+ list->Reset();
+ while (!list->End()) Push(list->ReadNext());
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Appends a copy of list2 to class object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::AppendCopy(List<Typ>* list2)
+{
+ List<Typ>* cpy=new List<Typ>;
+ cpy->Copy(list2);
+ Append(cpy);
+ delete cpy; cpy = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Appends list2 to class object
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::Append(List<Typ>* list)
+{
+ if (this==list) { AppendCopy(list); return;}
+ (tail->prev)->next = list->head->next;
+ (list->head->next)->prev = tail->prev;
+ if (current==tail) current=tail->prev;
+ ListEl<Typ>* t=tail;
+ tail = list->tail;
+ size += list->size;
+
+// Reuse old tail as new tail t for list2 and initialize pointers for empty list
+ list->tail=t;
+ list->head->next=t;
+ t->prev=list->head;
+ t->next=t;
+ list->head->prev=list->head;
+ t->data=list->head->data;
+ list->current=list->head;
+ list->size = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Use QUICKSORT to sort list in ascending order between two list elements
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::SortList(ListEl<Typ>* left, ListEl<Typ>* right, int sz)
+{
+ if (sz<=1) return; // when SortList() is called, left=head->next, right=tail->prev
+ ListEl<Typ> *l=left->prev, *r=right->next;
+
+ // Choose *random* pivot element!!
+ // (Otherwise, complexity for an already sorted list is N^2 => recursive calls may lead to stack overflow)
+ ListEl<Typ> *c=left;
+ for (int i=1; i<(int)(float(rand())*sz/(RAND_MAX+0.999)); i++) c = c->next;
+ SwapContent(left,c);
+
+ Typ pivot = left->data;
+// Typ* pivot= &(left->data);
+ int sz0=sz+1;
+ // cout<<"Sorting between "<<left->data<<" and "<<right->data<<". Pivot="<<pivot<<endl;
+ while(1)
+ {
+// PrintList();
+ do {r=r->prev; sz0--;} while (pivot < r->data);
+ do l=l->next; while (l->data < pivot);
+ if (l==r || l->prev==r) break;
+ SwapContent(l,r);
+ }
+ SortList(left,r,sz0);
+ SortList(r->next,right,sz-sz0);
+ pivot = tail->data; // to avoid calling the destructor of Typ on some real data element
+ }
+
+////////////////////////////////////////////////////////////////////////////
+// Use QUICKSORT to sort list of POINTERS by comparing the objects the pointers point to
+////////////////////////////////////////////////////////////////////////////
+template <class Typ>
+void List<Typ>::SortPointerList(ListEl<Typ>* left, ListEl<Typ>* right)
+{
+ if (right==left || right->next==left) return;
+ ListEl<Typ> *l=left->prev, *r=right->next;
+ Typ pivot=left->data;
+// cout<<"Sorting between "<<left->data<<" and "<<right->data<<". Pivot="<<pivot<<endl;
+ while(1)
+ {
+// PrintList();
+ do
+ {
+ r=r->prev;
+// cout<<"r=r->prev. r->data="<<r->data<<endl;
+ } while(*pivot < *(r->data));
+ do
+ {
+ l=l->next;
+// cout<<"l=l->next l->data="<<l->data<<endl;
+ } while (*(l->data) < *pivot);
+ if (l==r || l->prev==r) break;
+ SwapContent(l,r);
+ }
+ SortPointerList(left,r);
+ SortPointerList(r->next,right);
+}
+
+// Use INSERTSORT to sort list in asscending order between two list elements. Use only for presorted lists, otherwise time O(N^2)!
+template <class Typ>
+void List<Typ>::ResortList()
+{
+ ListEl<Typ> *c; // current element to be sorted in. Everything to the left is already sorted
+ ListEl<Typ> *n; // next element to be sorted in
+ ListEl<Typ> *p; // pointer for looping through sorted part of list
+ ListEl<Typ> *pnext; // for swapping
+ if (Size()<=1) return;
+ c=head->next->next;
+ while (c!=tail)
+ {
+ p=c->prev;
+ n=c->next;
+ if (c->data < p->data)
+ {
+ do {p=p->prev;} while (p!=head && c->data < p->data);
+ // Connect c->prev to c->next ...
+ c->next->prev=c->prev;
+ c->prev->next=c->next;
+ // ... and insert c between p and p->next ...
+ pnext=p->next;
+ p->next=c;
+ c->next=pnext;
+ pnext->prev=c;
+ c->prev=p;
+ }
+ c=n;
+ }
+}
+
+
+#endif /* JLIST */
+
+
+// //Main program: test class List
+
+// int main()
+// {
+// int p;
+// List<int>* plist=new List<int>(11);
+// List<int> list(22);
+
+// plist->Push(24);
+// plist->Push(18);
+// plist->Push(3);
+// plist->Enqueue(17);
+// plist->Enqueue(29);
+// printf("List 1 with pushed and enqueued elements:\n");
+// plist->PrintList();
+
+// list.Push(222);
+// printf("List 1 with list 2 appended:\n");
+// plist->Append(&list);
+// plist->PrintList();
+
+// printf("Pushing one element three times into list 2:\n");
+// list.Push(333);
+// list.Push(444);
+// list.Push(555);
+// printf("Printing plist and list with three elements:\n");
+// list.PrintList();
+// plist->PrintList();
+
+// printf("list.Copy(plist). Printing list 1 and 2:\n");
+// list.Copy(plist);
+// plist->PrintList();
+// list.PrintList();
+
+// printf("Appending list 1 to itself:\n");
+// plist->Append(plist);
+// plist->PrintList();
+
+// cout<<"Popping "<<plist->Pop()<<"\n";
+// cout<<"Popping "<<plist->Pop()<<"\n";
+// plist->PrintList();
+
+// cout<<"Dequeing "<<plist->Dequeue()<<"\n";
+// cout<<"Dequeing "<<plist->Dequeue()<<"\n";
+// plist->PrintList();
+
+// cout<<"Reversing list\n";
+// plist->Reverse();
+// plist->PrintList();
+
+// cout<<"Reversing to original list\n";
+// plist->Reverse();
+// plist->PrintList();
+
+// for (p=plist->Reset(); p>=5;p--)
+// {cout<<plist->GetPos()<<": "<<plist->Read(p)<<"\n";}
+
+// cout<<"Deleting "<<plist->Delete()<<"\n";
+// cout<<"Deleting "<<plist->Delete()<<"\n";
+// plist->PrintList();
+
+// plist->Append(plist);
+// plist->PrintList();
+// cout<<"List 1 sorted:\n";
+// plist->SortList();
+// plist->PrintList();
+
+// }