#ifndef LISTNODE_H#define LISTNODE_H#define position listnode<T>*
template <typename T>struct listnode
{
T data;
position pred;
position succ;listnode(){};listnode(T e, position p = nullptr, position s = nullptr):data(e),head(p),tail(s){}
listnode &insertAsPred(const T &e){
position x = new listnode(e, pred, this);
pred->succ = x;
this->pred = x;}
listnode &insertAsSucc(const T &e);};#endif
#ifndef LIST_H#define LIST_H#include"listnode.h"
template <typename T>
class List
{
private:int size;
position header;
position trailer;
public:voidinit();
T operator[](int r)const;
listnode<T>&first();
listnode<T>&find(T const& e,int n, position p)const;
position insertBefore(position p, T const&e);voidcopyNodes(position p,int n);
T remove(position p);~List();intclear();intdeduplicate();//Oerdered List operationintuniquify();
position search(T const& e,int n, position p)const;//SelectionSortvoidselectionSort(position p,int n);
position selectionMax(position p,int n);voidinsertionSort(position p,int n);};#endif
template<typename T>void List<T>::init(){
header = new listnode<T>;
trailer = new listnode<T>;
header->succ = trailer;
header->pred = nullptr;
header->data =0;
trailer->pred = header;
trailer->succ = nullptr;
trailer->data =0;
size =0;}
template<typename T>
T List<T>::operator[](int r)const{
position p =first();while(0<--r){
p = p->succ;return p->data;}}
template<typename T>
listnode<T>&List<T>::first(){return header->succ;}
template<typename T>
listnode<T>&List<T>::find(T const& e,int n, position p)const{while(0<--n){if(e ==(p->pred)->data){return p;}}return nullptr;}
template<typename T>
position List<T>::insertBefore(position p, T const&e){++size;return p->insertAsPred();}
template<typename T>void List<T>::copyNodes(position p,int n){init();while(n--){insertBeLast(p->data);
p = p->succ;}}
template<typename T>
T List<T>::remove(position p){
T e = p->data;
p->pred->succ = p->succ;
p->succ->pred = p->pred;
delete p;--size;return e;}
template<typename T>
List<T>::~List(){clear();
delete header;
delete trailer;}
template<typename T>int List<T>::clear(){int oldSize = size;while(0< size){remove(header->succ);}return oldSize;}
template <typename T>int List<T>::deduplicate(){if(size <2){return0;}int oldSize = size;
position p =first();int r =1;while(trailer !=(p->succ)){
position q =find(p->data,r,p);
q?remove(q):++r;}return oldSize - size;}
template <typename T>int List<T>::uniquify(){if(size <2){return0;}int oldSize = size;
position p =first();
position q;while(trailer !=(q=p->succ)){if(p->data != q->data){
p=q;}else{remove(q);}}return oldSize -size;}
template <typename T>
position List<T>::search(T const& e,int n, position p)const{while(0< n--){if(((p->pred)->data)<=e){break;}}return p;}
template <typename T>void List<T>::selectionSort(position p,int n){
position head = p->pred;
position tail = p;for(int i =0; i < n; i++){
tail = tail->succ;}while(1< n){insertBefore(tail,remove(selectionMax(head->succ, n)));
tail = tail->pred;
n--;}}
template <typename T>
position List<T>::selectionMax(position p,int n){
position max = p;for(position current = p;1< n; n--)if(((current = current->succ)->data)<=(max->data)){
max = current;}return max;}
template <typename T>void List<T>::insertionSort(position p,int n){for(int r =0; r < n; r++){insertAfter(search(p->data, r, p), p->data);
p = p->succ;remove(p->pred);}}