1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| class liste
{
public:
/* une liste peut être créée par défaut et sera vide */
liste():first(0),last(0);
/* une liste peut être créée avec un noeud unique */
liste(noeud * n):first(new noeud(n)),last(first){}
/* une liste peut etre créée au départ d'un écart entre [f, e)
*/
list(node * f, node * e)
{
node *temp=f;
/* pour chaque noeud apparaissant dans l'écart, nous insérons
* une copie en fin de liste
*/
while(temp!=e)
{
push_back(*temp);
++temp;
}
}
/* le destructeur de la liste doit détruire tous les noeuds qu'elle
* constient
*/
~liste()
{
clear();
}
/* nous pouvons copier une liste */
liste(liste const & rhs)
{
for(node* it=rhs.begin();it!=rhs.end(); ++it)
push_back(*it);
}
/* et assigner une liste à une autre (la liste de destination
* étant une copie de la liste d'origine)
*/
liste& operator = (liste const & rhs)
{
liste temp(rhs);
std::swap(first,temp->first);
std::swap(last,temp->last);
return *this;
}
/* il est intéressant de savoir si la liste est vide */
bool empty() const{return first!=0;}
/* ainsi que de savoir le nombre d'éléments qu'elle contient */
size_t size() const
{
node * temp=first;
size_t ret=0;
while(temp)
{
++temp;
++ret;
}
return ret;
}
/* on peut ajouter une valeur en début de liste */
void push_front(std::string const & s)
{
node * temp=new node(s);
temp->next=first;
/* c'est peut être le premier noeud ajouté */
if(!last)
last=temp;
}
/* ou ajouter une valeur en fin de liste */
void push_back(std::string const & s)
{
node * temp=new node(s);
/* s'il y a déjà un dernier noeud, nous relions le noeud
* fraichement créé au dernier
*/
if(last)
last->next = temp;
/* le noeud fraichment créé devient le dernier */
last = temp;
/* mais c'est aussi peut être le premier noeud ajouté */
if(!first)
first = temp;
}
/* on peut retirer le premier noeud de la liste
*
* cette opération se fait en temps constant (si nous avions eu
* une liste doublement chainée, nous aurions pu envisager de
* supprimer également le dernier noeud de la liste en temps
* constant... comme ce n'est pas le cas, nous nous abstenons ;) )
*/
void pop()
{
node* temp=++first;
delete first;
first=temp;
/*c'était peut etre le seul élément de la liste */
if(!first)
last=0;
}
/* il est intéressant de fournir l'acces au premier
* élément de la liste et à ce qui suit le dernier élément de la
* liste
*
* de manière non constante
*/
node* begin(){return first;}
node* end(){return 0;}
/* et de manière constante */
node const * begin() const{return first;}
node const * end() const{return 0;}
/* enfin, nous pouvons souhaiter vider l'ensemble de la liste */
void clear()
{
while(first)
{
node * temp=++first;
delete first;
first=temp;
}
}
private:
/* le premier élément de la liste */
node * first;
/* et le dernier (qui nous permet d'ajouter un dernier noeud
* en temps constant )
*/
node * last;
}; |