Lista doblemente enlazada

Moderador: ivancp

Temas sobre programacion en C/C++ (no Visual C++)

Lista doblemente enlazada

Notapor latindev » Lun Ene 08, 2007 6:46 pm

Amigos.

A quienes esten interesados en resolver problemas de la ACM (http://acm.uva.es/problemset/ ), quiero compartir con ustedes una clase que escribí para resolver uno de esos problemas, esta clase tambien les servirá para muchos otros.

Se trata de una lista doblemente enlazada circular, la implementé justo para estos propositos. Con esta clase he podido resolver varios problemas como el 330.

No dejen de programar, cualquier duda acerca del funcionamiento de la clase solo escriban.

La clase todavia esta en pañales pero es util, Se aceptan sugerencias.

Enjoy!

Código: Seleccionar todo
  1.  

  2.  

  3. /* CLinkedList, A circular double-linked list.

  4.  *  Version: 0.3

  5.  *  Author: Ivan Cachicatari ivancp@latindevelopers.com

  6.  *  Last Update: 03:40am 08-10-2006

  7.  *

  8.  * Please use and enjoy. Please let me know of any bugs/mods/improvements

  9.  * that you have found/implemented and I will fix/incorporate

  10.  * them into this file.

  11.  */

  12.  

  13. template <typename>

  14. class CLinkedList

  15. {

  16.   public:

  17.  

  18.    struct NODE

  19.    {

  20.       T *m_data;      

  21.       NODE *pNext;

  22.       NODE *pPrev;

  23.       bool bIsHead;

  24.       NODE(T *data) : m_data(data)

  25.       {

  26.          bIsHead = false;

  27.          pNext = pPrev = this;        

  28.       }

  29.       NODE* next()

  30.       {

  31.          if(pNext->bIsHead)

  32.             return NULL;

  33.          return pNext;

  34.       }

  35.       void insertAfter(NODE *&prevNode)

  36.       {

  37.          remove();

  38.  

  39.          pPrev = prevNode;

  40.          pNext = prevNode->pNext;

  41.          prevNode->pNext->pPrev= this;

  42.          prevNode->pNext= this;

  43.       }

  44.  

  45.       void insertBefore(NODE *&nextNode)

  46.       {

  47.          remove();

  48.  

  49.          pPrev = nextNode->pPrev;

  50.          pNext = nextNode;

  51.          nextNode->pPrev->pNext = this;

  52.          nextNode->pPrev= this;

  53.          

  54.       }

  55.  

  56.       void remove()

  57.       {

  58.          pNext ->pPrev = pPrev;

  59.          pPrev ->pNext = pNext;

  60.          pPrev = pNext = this;        

  61.       }

  62.    };

  63.  

  64.    int m_nCount;

  65.    NODE *m_pRoot;

  66.    int (*m_lpfnCompare)(const T *a,const T *b);

  67.  

  68.    // Constructor, input: a compare function

  69.  

  70.    CLinkedList(int (*lpfnCompare)(const T *a,const T *b))

  71.    {

  72.       m_pRoot = NULL;

  73.       m_lpfnCompare = lpfnCompare;

  74.       m_nCount = 0;

  75.    }

  76.  

  77.    ~CLinkedList()

  78.    {

  79.       Empty();

  80.    }

  81.  

  82.    // Inserts a unique sorted item, returns false if exists.

  83.    bool Insert(T *&newValue, bool bUnique = false)

  84.    {

  85.       if(!m_pRoot)

  86.       {

  87.          m_pRoot = new NODE(newValue);

  88.          m_pRoot->bIsHead = true;

  89.          m_nCount++;

  90.          //cout<<" + "<<m_pRoot>m_data->name<<"            [as root]"<<endl>m_data);

  91.          

  92.          // 1 newValue > pTmp->m_data

  93.          // -1 newValue <pTmp>m_data

  94.  

  95.          if(bUnique && res == 0 ) // equal

  96.             return false;

  97.          if(res < 0) // newValue <pTmp>m_data

  98.          {

  99.             newNode->insertBefore(pTmp);

  100.  

  101.             if (pTmp == m_pRoot)

  102.             {

  103.                m_pRoot->bIsHead = false;

  104.                newNode->bIsHead = true;

  105.                m_pRoot = newNode;

  106.             }

  107.             m_nCount++;

  108.  

  109.             //cout<<" + "<<newNode>m_data->name<<"            ["<<i<<"]"<<endl>next();

  110.       }

  111.       m_nCount++;

  112.       newNode->insertBefore(m_pRoot);

  113.       //cout<<" + "<<newNode>m_data->name<<"["<<i<<"]"<<endl>pNext;

  114.          delete toDelete->m_data;

  115.          delete toDelete;

  116.          toDelete = NULL;        

  117.       }

  118.       m_nCount = 0;

  119.    }

  120.  

  121.    void Delete(T*& item)

  122.    {

  123.       NODE *pTmp = m_pRoot;

  124.  

  125.       if(m_nCount == 1)

  126.       {

  127.          delete m_pRoot->m_data;

  128.          delete m_pRoot;

  129.          m_pRoot = NULL;

  130.          m_nCount--;

  131.          return;

  132.       }

  133.  

  134.       while(pTmp)

  135.       {

  136.          if(pTmp->m_data == item)

  137.          {

  138.             NODE *&toDelete = pTmp;

  139.  

  140.             if(toDelete == m_pRoot)

  141.             {

  142.                NODE *&pTmp2 = m_pRoot->pNext;

  143.  

  144.                m_pRoot->pPrev->pNext = m_pRoot->pNext;

  145.                m_pRoot->pNext->pPrev = m_pRoot->pPrev;

  146.                m_pRoot = m_pRoot->pNext;

  147.                m_pRoot->bIsHead = true;

  148.  

  149.             }

  150.             else

  151.             {

  152.                (NODE *&)pTmp->pPrev->pNext = toDelete->pNext;

  153.                (NODE *&)pTmp->pNext->pPrev = toDelete->pPrev;

  154.             }

  155.  

  156.             delete toDelete->m_data;

  157.             delete toDelete;

  158.             toDelete = NULL;

  159.             m_nCount--;

  160.             return;

  161.          }

  162.          pTmp = pTmp->next();

  163.       }      

  164.    }

  165.    void Print()

  166.    {

  167.       NODE *pTmp = m_pRoot;

  168.      

  169.       if (!m_pRoot)

  170.       {

  171.          cout<<"\nEmpty\n";

  172.          return;

  173.       }

  174.       while(true)

  175.       {

  176.          cout<<pTmp>m_data->name<<pTmp>bIsHead?"[root]":"")<<endl>pNext;

  177.          if(pTmp == m_pRoot)

  178.             break;

  179.       }

  180.    }

  181.  

  182.    T*& operator[](int nIndex) const

  183.    {

  184.       NODE *pTmp = m_pRoot;

  185.       for(int i = 0 ; i <m_nCount>= nIndex || !pTmp->next())

  186.             return pTmp->m_data;

  187.          pTmp = pTmp->next();

  188.       }

  189.       return pTmp->m_data;

  190.    }  

  191. };




Nota:
El codigo es resultado de sugerencias y experiencias propias de varios años. Tuve que reescribir la clase.


Ejemplo de utilizacion:

Código: Seleccionar todo
  1. struct ITEM

  2. {

  3.    char name[10];

  4.    double cost;

  5.    double price;

  6.    long onHand;

  7.    bool bSold;

  8.    ITEM():onHand(0),bSold(false){}

  9. };

  10.  

  11. inline int fnITEMCompare( const ITEM *a, const ITEM *b)

  12. {

  13.    return strcmp(a->name,b->name);

  14. }

  15.  

  16. int main(int argc, char* argv[])

  17. {

  18.    CLinkedList<ITEM> items(fnITEMCompare);

  19.  

  20.    ITEM *item = new ITEM();

  21.    strcpy(item->name,"Primer Item");

  22.    item->cost = 45;

  23.    item->price = 30.2;

  24.    items.Insert(item,true);

  25.  

  26.    ITEM *item2 = new ITEM();

  27.    strcpy(item2->name,"Segundo Item");

  28.    item2->cost = 65;

  29.    item2->price = 50.2;

  30.    items.Insert(item2,true);

  31.  

  32.    items.Print();

  33.    return 0;

  34. }

Imagen
Avatar de Usuario
latindev
Administrador
Administrador
 
Mensajes: 1062
Registrado: Lun Jun 02, 2003 8:30 pm
Ubicación: Peru


Re: Lista doblemente enlazada

Notapor lester » Vie Nov 07, 2008 1:45 pm

coloca esto en el punto h de una unit llamada Lista y veras
aqui tienes La Enlazada, La circular, La secuencial, tienes pilas colas etc




//---------------------------------------------------------------------------

#ifndef ListaH
#define ListaH
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>

//---------------------------------------------------------------------------
// comun
//---------------------------------------------------------------------------

class EListException{};
class EListOutOfMemory : public EListException{};
class EListOutOfRange : public EListException{};

//---------------------------------------------------------------------------
// Secuencial
//---------------------------------------------------------------------------


template<class Elemento>
class TListaSec {
typedef void (*TFuncionAccion)(Elemento&, void* referencia = NULL);
typedef bool (*TFuncionCondicional)(Elemento&, void* referencia = NULL);
public:
// constructores y destructores
TListaSec();
TListaSec(const Elemento&);
TListaSec(const TListaSec<Elemento>&);
~TListaSec();

// operaciones públicas
virtual void Insertar(const Elemento&, int);
virtual void Anadir(const Elemento&);
virtual Elemento& Obtener(int) const;
virtual Elemento& Eliminar(int);
int Longitud() const;
bool Vacia() const;

void ParaCada(TFuncionAccion, void*);
Elemento* PrimeroQueCumple(TFuncionCondicional, void*);
protected:
int longitud, tamano;
Elemento* elementos;

private:
};

template<class Elemento>
class TPilaSec : protected virtual TListaSec<Elemento> {
public:
// constructores y destructores
TPilaSec(): TListaSec<Elemento>() { primero = -1; }
TPilaSec(const Elemento &nuevo)
: TListaSec<Elemento>(nuevo) { primero = 0; }
TPilaSec(const TPilaSec<Elemento> &otraPila)
: TListaSec<Elemento>(otraPila) { primero = longitud - 1; }
~TPilaSec() {}

// operaciones públicas
void Anadir(const Elemento&);
Elemento& Primero() const;
Elemento& Eliminar();

using TListaSec<Elemento> :: Longitud;
using TListaSec<Elemento> :: Vacia;
protected:
int primero;
private:
};

template<class Elemento>
class TColaSec : protected virtual TListaSec<Elemento>{
public:
// Constructores y destructores
TColaSec(): TListaSec<Elemento>() { primero = 0; ultimo = tamano - 1; }
TColaSec(const Elemento &nuevo)
: TListaSec<Elemento>(nuevo) { primero = 0; ultimo = 0;}
TColaSec(const TColaSec<Elemento> &otraCola)
: TListaSec<Elemento>(otraCola) { primero = 0; ultimo = longitud - 1; }
~TColaSec() {}

// Operaciones públicas
void Anadir(const Elemento&);
Elemento& Eliminar();
Elemento& Primero() const;
using TListaSec<Elemento> :: Longitud;
using TListaSec<Elemento> :: Vacia;
protected:
int primero, ultimo;
private:
};

//---------------------------------------------------------------------------
// Enlazada
//---------------------------------------------------------------------------

template<class Type> class TListaEnlazada;
template<class Type> class TListaEnlazadaCircular;
template<class Type> class TListaDoblementeEnlazada;
template<class Type> class TColaEnlazada;
template<class Type> class TPilaEnlazada;

template<class Elemento>
class TNodo{
friend TListaEnlazada<Elemento>;
friend TListaEnlazadaCircular<Elemento>;
friend TColaEnlazada<Elemento>;
friend TPilaEnlazada<Elemento>;
protected:
Elemento dato;
TNodo<Elemento> *siguiente;

TNodo() {}
TNodo(const Elemento&);
};

template<class Elemento>
class TNodoDoble : public TNodo<Elemento> {
friend TListaDoblementeEnlazada<Elemento>;
protected:
TNodoDoble<Elemento> *anterior;

TNodoDoble();
TNodoDoble(const Elemento&);
};


template<class Elemento>
class TListaEnlazada {
typedef void (*TFuncionAccion)(Elemento&, void* referencia = NULL);
typedef bool (*TFuncionCondicional)(Elemento&, void* referencia = NULL);
public:
TListaEnlazada();
TListaEnlazada(const Elemento&);
TListaEnlazada(const TListaEnlazada<Elemento>&);
~TListaEnlazada();

virtual void Insertar(const Elemento&, int);
virtual void Anadir(const Elemento&);
virtual Elemento& Obtener(int) const;
virtual Elemento& Eliminar(int);
inline int Longitud() const { return longitud; }
inline bool Vacia() const { return !longitud; }

void ParaCada(TFuncionAccion, void*);
Elemento* PrimeroQueCumple(TFuncionCondicional, void*);
protected:
int longitud;
TNodo<Elemento> *primero;

private:
};

template<class Elemento>
class TListaDoblementeEnlazada : public TListaEnlazada<Elemento> {
public:
TListaDoblementeEnlazada() : TListaEnlazada<Elemento>() {}
TListaDoblementeEnlazada(const Elemento&);
TListaDoblementeEnlazada(const TListaEnlazada<Elemento>&);
~TListaDoblementeEnlazada() {}

void Insertar(const Elemento&, int);
void Anadir(const Elemento&);
void Eliminar(int);
protected:
private:
};

template<class Elemento>
class TListaEnlazadaCircular : public TListaEnlazada<Elemento> {
public:
TListaEnlazadaCircular() : TListaEnlazada<Elemento>() {}
TListaEnlazadaCircular(const Elemento&);
TListaEnlazadaCircular(const TListaEnlazadaCircular<Elemento>&);
~TListaEnlazadaCircular();

void Insertar(const Elemento&, int);
void Anadir(const Elemento&);
void Eliminar(int);
protected:
private:
};

template<class Elemento>
class TPilaEnlazada : protected virtual TListaEnlazada<Elemento> {
public:
// constructores y destructores
TPilaEnlazada() : TListaEnlazada<Elemento>() {}
TPilaEnlazada(const Elemento &nuevo) : TListaEnlazada<Elemento>(nuevo) {}
TPilaEnlazada(const TPilaEnlazada<Elemento>&);
~TPilaEnlazada() {}

// operaciones públicas
void Anadir(const Elemento&);
Elemento& Primero() const;
Elemento& Eliminar();

using TListaEnlazada<Elemento> :: Longitud;
using TListaEnlazada<Elemento> :: Vacia;
protected:
// no necesita nada más, lo hereda todo.
private:
};

template<class Elemento>
class TColaEnlazada : private virtual TListaEnlazada<Elemento> {
public:
// Constructores y destructores
TColaEnlazada() : TListaEnlazada<Elemento>() { ultimo = NULL; }
TColaEnlazada(const Elemento &nuevo)
: TListaEnlazada<Elemento>(nuevo) { ultimo = primero; }
TColaEnlazada(const TColaEnlazada<Elemento>&);
~TColaEnlazada() {}

// Operaciones públicas
void Anadir(const Elemento&);
Elemento& Eliminar();
Elemento& Primero() const;

using TListaEnlazada<Elemento> :: Longitud;
using TListaEnlazada<Elemento> :: Vacia;
protected:
TNodo<Elemento> *ultimo;
private:
};

//---------------------------------------------------------------------------
// I M P L E M E N T A C I O N
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// template<class Elemento> TListaSec<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
TListaSec<Elemento> :: TListaSec ()
{
tamano = 2;
elementos = new Elemento[tamano];
longitud = 0;
};

template<class Elemento>
TListaSec<Elemento> :: TListaSec (const Elemento &nuevoElemento)
{
tamano = 2;
elementos = new Elemento[tamano];
elementos[0] = nuevoElemento;
longitud = 1;
};

template<class Elemento>
TListaSec<Elemento> :: TListaSec (const TListaSec <Elemento> &listaOrigen)
{
int cantidadElementos = listaOrigen.Longitud();

if (cantidadElementos == 0)
TListaSec :: TListaSec();
else{
tamano = cantidadElementos;
elementos = new Elemento[tamano];
longitud = 0;

for (int i = 1; i <= listaOrigen.Longitud(); i++)
Anadir(listaOrigen.Obtener(i));
}

};

template<class Elemento>
TListaSec<Elemento> :: ~TListaSec ()
{
delete [] elementos;
};

template<class Elemento>
void TListaSec<Elemento> :: Anadir(const Elemento& elementoNuevo)
// precondiciones:
// postcondiciones insertar el elementoNuevo
{
if (tamano == longitud) { // factor de carga es 1
tamano *= 2; // duplico el tamano del array
Elemento* nuevoArreglo = new Elemento[tamano];

for (int i = 0; i <= longitud - 1; i++) // copia la primera parte
nuevoArreglo[i] = elementos[i];

nuevoArreglo[longitud] = elementoNuevo; // coloco el nuevo elemento

delete [] elementos;
elementos = nuevoArreglo;
}
else { // factor de carga es < 1
elementos[longitud] = elementoNuevo;
}

longitud++;
};


template<class Elemento>
void TListaSec<Elemento> :: Insertar(const Elemento& elementoNuevo, int pos)
// precondiciones: pos, posición donde quiero insertar elementoNuevo
// postcondiciones si se puede se insertar el elementoNuevo de lo contrario se lanza una excepcion
{
if (pos <= 0 || pos > longitud) throw EListOutOfRange();

if (tamano == longitud) { // factor de carga es 1
tamano *= 2; // duplico el tamano del array
Elemento* nuevoArreglo = new Elemento[tamano];

for (int i = 0; i < pos - 1; i++) // copia la primera parte
nuevoArreglo[i] = elementos[i];

nuevoArreglo[pos - 1] = elementoNuevo; // coloco el nuevo elemento

for (int i = pos; i <= longitud; i++) // copia la segunda parte
nuevoArreglo[i] = elementos[i - 1];

delete [] elementos;
elementos = nuevoArreglo;
}
else { // factor de carga es < 1
for (int i = longitud; i >= pos; i--)
elementos[i] = elementos[i - 1];
elementos[pos - 1] = elementoNuevo;
}

longitud++;
};

template<class Elemento>
Elemento& TListaSec<Elemento> :: Obtener(int pos) const
// precondiciones: pos, posición del elemento que quiero devolver
// postcondiciones: retorna el elemento si que esta en la posicion "pos",
// en caso contrario levanta una execpción
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

return elementos[pos - 1];
};

template<class Elemento>
Elemento& TListaSec<Elemento> :: Eliminar(int pos)
{
if (pos <= 0 || pos > longitud) throw EListOutOfRange();

// duplico el elemento
Elemento *elementoDevolver = new Elemento;

(*elementoDevolver) = elementos[pos - 1];

for (int i = pos; i < longitud; i++)
elementos[i - 1] = elementos[i];

longitud--;

return *elementoDevolver;
};

template<class Elemento>
int TListaSec<Elemento> :: Longitud() const
// postcondiciones: retorna la cantidad de elementos que hay en la lista
{
return longitud;
};

template<class Elemento>
bool TListaSec<Elemento> :: Vacia() const
// postcondiciones: retorna true si esta vacia
{
return !longitud;
};

template<class Elemento>
void TListaSec<Elemento> :: ParaCada(TFuncionAccion fAccion, void *referencia = NULL)
{
for(int i = 0; i < longitud; i++)
fAccion(elementos[i], referencia);
};

template<class Elemento>
Elemento* TListaSec<Elemento> :: PrimeroQueCumple(TFuncionCondicional fCondicion, void *referencia = NULL)
{
int i = 0;
bool encontrado = false;
while ((i < longitud) && !encontrado){
if (fCondicion(elementos[i], referencia))
encontrado = true;
else
i++;
}

return ((encontrado)? &elementos[i] : NULL);
};

//---------------------------------------------------------------------------
// template<class Elemento> TPilaSec<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
void TPilaSec<Elemento> :: Anadir(const Elemento &elementoNuevo)
{
TListaSec<Elemento> :: Anadir(elementoNuevo);
primero++;
};

template<class Elemento>
Elemento& TPilaSec<Elemento> :: Primero() const
{
if (longitud == 0) throw EListOutOfRange();
return elementos[primero];
};

template<class Elemento>
Elemento& TPilaSec<Elemento> :: Eliminar()
{
if (longitud == 0) throw EListOutOfRange();

// duplico el elemento
Elemento *elementoDevolver = new Elemento;

(*elementoDevolver) = elementos[primero];

longitud--;
primero--;

return *elementoDevolver;
};

//---------------------------------------------------------------------------
// template<class Elemento> TColaSec<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
void TColaSec<Elemento> :: Anadir(const Elemento &elementoNuevo)
{
if (tamano != longitud){
// Cola NO llena

ultimo = (ultimo + 1) % tamano;
elementos[ultimo] = elementoNuevo;
}
else{ // Cola LLENA, necesito duplicarla

tamano *= 2; // duplico el tamano del array
Elemento* nuevoArreglo = new Elemento[tamano];

// Copia el arreglo (longitud = tamaño ante de duplicar)
// a partir de la posición del primer elemento
int cursor = primero;
for (int i = 0; i < longitud ; i++){
nuevoArreglo[i] = elementos[cursor];
cursor = (cursor + 1) % longitud;
}

// Inserto el nuevo elemento
nuevoArreglo[longitud] = elementoNuevo;

// Reasigno los valores de primero y ultimo
primero = 0;
ultimo = longitud;

// Elimino el arreglo viejo y asigno el nuevo
delete [] elementos;
elementos = nuevoArreglo;
}

longitud++;
};

template<class Elemento>
Elemento& TColaSec<Elemento> :: Primero() const
{
if (longitud == 0) throw EListOutOfRange();
return elementos[primero];
}

template<class Elemento>
Elemento& TColaSec<Elemento> :: Eliminar()
{
if (longitud == 0) throw EListOutOfRange();

// duplico el elemento
Elemento *elementoDevolver = new Elemento;

(*elementoDevolver) = elementos[primero];

// avanzo el indicador primero
primero = (primero + 1) % tamano;

longitud--;

return *elementoDevolver;
};


//---------------------------------------------------------------------------
// template<class Elemento> TListaEnlazada<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
TNodo<Elemento> :: TNodo(const Elemento &elementoNuevo)
{
dato = elementoNuevo;
siguiente = NULL;
};


template<class Elemento>
TListaEnlazada<Elemento> :: TListaEnlazada()
{
longitud = 0;
primero = NULL;
};

template<class Elemento>
TListaEnlazada<Elemento> :: TListaEnlazada(const Elemento &elementoNuevo)
{
primero = new TNodo<Elemento>(elementoNuevo);
longitud = 1;
};

template<class Elemento>
TListaEnlazada<Elemento> :: ~TListaEnlazada()
{
TNodo<Elemento> *cursor;

while(primero){
cursor = primero;
primero = primero->siguiente;
delete cursor;
}
};

template<class Elemento>
void TListaEnlazada<Elemento> :: Anadir(const Elemento &elementoNuevo)
// precondiciones:
// postcondiciones:
{
TNodo<Elemento> *nodoNuevo = new TNodo<Elemento>(elementoNuevo);
TNodo<Elemento> *cursor = primero;

if (primero != NULL){
while (cursor->siguiente)
cursor = cursor->siguiente;

cursor->siguiente = nodoNuevo;
}
else
primero = nodoNuevo;

longitud++;
};

template<class Elemento>
void TListaEnlazada<Elemento> :: Insertar(const Elemento &elementoNuevo, int pos)
// precondiciones: pos, posición donde quiero insertar elementoNuevo
// postcondiciones si se puede se insertar el elementoNuevo de lo contrario se lanza una excepcion
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

TNodo<Elemento> *nodoNuevo = new TNodo<Elemento>(elementoNuevo);

if (pos != 1){
TNodo<Elemento> *cursor = primero;
int contador = 1;
while (contador < pos - 1){ // me posiciono en el nodo anterior
cursor = cursor->siguiente;
contador++;
}

nodoNuevo->siguiente = cursor->siguiente;
cursor->siguiente = nodoNuevo;
}
else{ // Insertar en la primera posición
nodoNuevo->siguiente = primero;
primero = nodoNuevo;
}

longitud++;
};

template<class Elemento>
Elemento& TListaEnlazada<Elemento> :: Obtener(int pos) const
// precondiciones: pos, posición del elemento que quiero devolver
// postcondiciones: retorna el elemento si que esta en la posicion "pos",
// en caso contrario levanta una execpción
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

TNodo<Elemento> *cursor = primero;
for (int i = 1; i < pos; i++)
cursor = cursor->siguiente;

return cursor->dato;
};


template<class Elemento>
Elemento& TListaEnlazada<Elemento> :: Eliminar(int pos)
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

TNodo<Elemento> *cursor = primero;

if (pos != 1){
for (int i = 1; i < pos - 1; i++)
cursor = cursor->siguiente;

// obtengo una referencia al nodo
TNodo<Elemento> *nodoEliminar = cursor->siguiente;

// lo saco de la lista
cursor->siguiente = nodoEliminar->siguiente;

cursor = nodoEliminar;
}
else // Eliminar el primer nodo
primero = primero->siguiente;


// duplico el elemento
Elemento *elementoDevolver = new Elemento;

(*elementoDevolver) = cursor->dato;

// destruyo el nodo
delete cursor;
longitud--;

// devuelvo la dirección donde esta el dato
return *elementoDevolver;
}

template<class Elemento>
void TListaEnlazada<Elemento> :: ParaCada(TFuncionAccion fAccion, void *referencia = NULL)
{
TNodo<Elemento>* cursor = primero;
while (cursor){
fAccion(cursor->dato, referencia);
cursor = cursor->siguiente;
}
};

template<class Elemento>
Elemento* TListaEnlazada<Elemento> :: PrimeroQueCumple(TFuncionCondicional fCondicion, void *referencia = NULL)
{
TNodo<Elemento> *cursor = primero;
bool encontrado = false;
while (cursor && !encontrado){
if (fCondicion(cursor->dato, referencia))
encontrado = true;
else
cursor = cursor->siguiente;
}

return ((encontrado)? &cursor->dato : NULL);
};

//---------------------------------------------------------------------------
// template<class Elemento> TListaDoblementeEnlazada<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
TNodoDoble<Elemento> :: TNodoDoble()
: TNodo<Elemento>()
{
anterior = NULL;
};

template<class Elemento>
TNodoDoble<Elemento> :: TNodoDoble(const Elemento &elementoNuevo)
: TNodo<Elemento>(elementoNuevo)
{
anterior = NULL;
};

template<class Elemento>
void TListaDoblementeEnlazada<Elemento> :: Anadir(const Elemento &elementoNuevo)
// precondiciones:
// postcondiciones:
{
TNodoDoble<Elemento> *nodoNuevo = new TNodoDoble<Elemento>(elementoNuevo);

TNodoDoble<Elemento> *cursor = (TNodoDoble<Elemento>*) primero;

if (primero != NULL){
while (cursor->siguiente)
cursor = (TNodoDoble<Elemento>*) cursor->siguiente;

cursor->siguiente = nodoNuevo;
nodoNuevo->anterior = cursor;
}
else
primero = nodoNuevo;

longitud++;
}

template<class Elemento>
void TListaDoblementeEnlazada<Elemento> :: Insertar(const Elemento &elementoNuevo, int pos)
// precondiciones: pos, posición donde quiero insertar elementoNuevo
// postcondiciones si se puede se insertar el elementoNuevo de lo contrario se lanza una excepcion
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

TNodoDoble<Elemento> *nodoNuevo = new TNodoDoble<Elemento>(elementoNuevo);

if (pos != 1){
TNodoDoble<Elemento> *cursor = (TNodoDoble<Elemento>*) primero;
int contador = 1;
while (contador < pos - 1){ // me posiciono en el nodo anterior
cursor = (TNodoDoble<Elemento>*) cursor->siguiente;
contador++;
}

nodoNuevo->siguiente = cursor->siguiente;
nodoNuevo->anterior = cursor;
cursor->siguiente = nodoNuevo;
((TNodoDoble<Elemento>*) nodoNuevo->siguiente)->anterior = nodoNuevo;
}
else{ // Insertar en la primera posición
nodoNuevo->siguiente = primero;
((TNodoDoble<Elemento>*) primero)->anterior = nodoNuevo;
primero = nodoNuevo;
}

longitud++;
};

template<class Elemento>
void TListaDoblementeEnlazada<Elemento> :: Eliminar(int pos)
{
//FALTA
};

//---------------------------------------------------------------------------
// template<class Elemento> TListaEnlazadaCircular<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
TListaEnlazadaCircular<Elemento> :: TListaEnlazadaCircular(const Elemento &elementoNuevo)
{
primero = new TNodo<Elemento>(elementoNuevo);
primero->siguiente = primero;
longitud = 1;
};

template<class Elemento>
TListaEnlazadaCircular<Elemento> :: ~TListaEnlazadaCircular()
{
if (primero){
TNodo<Elemento> *cursor, *salvaPrimero;

salvaPrimero = primero;

// ejecuto si hay más de 1 elemento
while(primero->siguiente != salvaPrimero ){
cursor = primero;
primero = primero->siguiente;
delete cursor;
}

delete primero;
primero = NULL;
longitud = 0;
}
};

template<class Elemento>
void TListaEnlazadaCircular<Elemento> :: Anadir(const Elemento &elementoNuevo)
// precondiciones:
// postcondiciones:
{
TNodo<Elemento> *nodoNuevo = new TNodo<Elemento>(elementoNuevo);

TNodo<Elemento> *cursor = primero;

if (primero != NULL){
while (cursor->siguiente != primero)
cursor = cursor->siguiente;

cursor->siguiente = nodoNuevo;
}
else
primero = nodoNuevo;

nodoNuevo->siguiente = primero;
longitud++;
}

template<class Elemento>
void TListaEnlazadaCircular<Elemento> :: Insertar(const Elemento &elementoNuevo, int pos)
// precondiciones: pos, posición donde quiero insertar elementoNuevo
// postcondiciones si se puede se insertar el elementoNuevo de lo contrario se lanza una excepcion
{
if ((pos <= 0) || (pos > longitud)) throw EListOutOfRange();

// salvo el cursor
TNodo<Elemento> *primeroSalva = primero;

TListaEnlazada<Elemento> :: Insertar(elementoNuevo, pos);

if (pos == 1){
// NO ES equivalente al TListaEnlazada::Insertar
// debo actualizar el puntero siguiente del ultimo nodo

TNodo<Elemento> *cursor = primeroSalva;
while (cursor->siguiente != primeroSalva)
cursor = cursor->siguiente;

cursor->siguiente = primero;
}
};

template<class Elemento>
void TListaEnlazadaCircular<Elemento> :: Eliminar(int pos)
{
//FALTA
}

//---------------------------------------------------------------------------
// template<class Elemento> TPilaEnlazada<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
void TPilaEnlazada<Elemento> :: Anadir(const Elemento &elementoNuevo)
{
if (longitud > 0)
Insertar(elementoNuevo, 1);
else
TListaEnlazada<Elemento> :: Anadir(elementoNuevo);
};


template<class Elemento>
Elemento& TPilaEnlazada<Elemento> :: Eliminar()
{
return TListaEnlazada<Elemento> :: Eliminar(1);
}

template<class Elemento>
Elemento& TPilaEnlazada<Elemento> :: Primero() const
{
if (longitud == 0) throw EListOutOfRange();

return primero->dato;
}

//---------------------------------------------------------------------------
// template<class Elemento> TColaEnlazada<Elemento>
//---------------------------------------------------------------------------

template<class Elemento>
void TColaEnlazada<Elemento> :: Anadir(const Elemento &elementoNuevo)
{
TListaEnlazada<Elemento> :: Anadir(elementoNuevo);

if (longitud > 1)
ultimo = ultimo->siguiente;
else
ultimo = primero;
}

template<class Elemento>
Elemento& TColaEnlazada<Elemento> :: Eliminar()
{
if (primero == ultimo) ultimo = NULL;
return TListaEnlazada<Elemento> :: Eliminar(1);
}

template<class Elemento>
Elemento& TColaEnlazada<Elemento> :: Primero() const
{
if (longitud == 0) throw EListOutOfRange();

return primero->dato;
}

//---------------------------------------------------------------------------
#endif
lester
Novato
Novato
 
Mensajes: 3
Registrado: Mié Nov 05, 2008 12:56 pm


Re: Lista doblemente enlazada

Notapor cyberMASTER » Jue Oct 14, 2010 8:27 pm

buenas noches amigo..
ante todo un saludo..
soy nuevo en el foro y llegue para aprender....

buscando y buscando en internet mucho sobre este tema LISTAS CIRCULARES DOBLEMENTE ENLAZADAS..
me encotre con este foro y su ejemplo.. ya q es de utilidad para mi....debo presentar un debate con un ejemplo comun de dicho tema..... y leyendo un poco su programa me gustaria saber q hace alli?

xq no lo puedo decifrar me da un error en la siguiente linea: return strcmp(a->name,b->name); al compilarlo me dice que no esta declarada y adicionalmente 6 errores mas.....

me podrias ayudar..

y muchas gracias por su apoyo....

saludos
cyberMASTER
Novato
Novato
 
Mensajes: 1
Registrado: Jue Oct 14, 2010 8:18 pm

Re: Lista doblemente enlazada

Notapor ivancp » Lun Oct 18, 2010 10:09 am

Hola
strcmp es una funcion que esta disponible en la libreria string.h para lo que tienes que agregar la directiva:
Código: Seleccionar todo
  1. #include <string.h>

Imagen @latindev | Mi Blog
Por favor lee las reglas del foro
Avatar de Usuario
ivancp
Colaborador
Colaborador
 
Mensajes: 680
Registrado: Jue Sep 06, 2007 12:58 pm


    

Volver a C/C++

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados