martes, 10 de julio de 2012

Estructuras dinámicas

Hola ,hace mucho tiempo que tenemos estructuras optimas para guardar datos como las listas genéricas o los treemap pero a modo de ejemplo vamos a reinventar la rueda.
Lo que intentaremos haces es una estructura doble con 2 apuntadores en memoria para que así puedas ir de derecha a izquierda y viceversa en cualquier momento.
Nos referimos a un nodo doble aquí unas imágenes para obtener una idea.
inicio
Nodo inicial con 2 apuntadores inicialmente a null
fin
El nodo final con la misma idea.
Agreguemos una estructura nueva se vería así:
nodo1
Aqui vemos un nodo inicio apuntando hacia un nodo con datos.
Si aplicamos la misma idea tendremos lo siguiente:
nodo n
Entonces tenemos una estructura dinámica en memoria ya que los datos se pierden al cerrar el programa o si es que apuntan los nodos inicio y fin a nulo así el recolector de basura los elimina.
Vamos de plano al código:
/**
 *
 * @author jonathan-palomino.blogspot.com
 */
//Clase para una lista doble :
public class NodoDoble {
	private Productos Producto;// informacion
	private NodoDoble ApuntAnt;	// enlace con el anterior
	private NodoDoble ApuntSgte;// enlace con el siguiente

	// constructor
	NodoDoble(Productos Producto){this.Producto=Producto;}
//Esta clase productos será una clase que podrá contener N datos que se podrán setear desde un aplicativo algo así como capas.
	// get/set
        void setPro(Productos Producto){this.Producto=Producto;}
	void setApuntSgte(NodoDoble ApuntSgte){this.ApuntSgte=ApuntSgte;}
	void setApuntAnt(NodoDoble ApuntAnt){this.ApuntAnt = ApuntAnt;}

	Productos getPro(){return Producto;	}
	NodoDoble getApuntSgte(){return ApuntSgte;	}
	NodoDoble getApuntAnt(){return ApuntAnt;	}
}// fin de la clase de nodo doble
Para la clase enlazadora donde podremos poner la lógica de agregación para que trabaje.

/**
 *
 * @author jonathan-palomino.blogspot.com
 */
public class ListaDobleConOrden{
	private NodoDoble inicio;
	private NodoDoble fin;

	// constructor
	ListaDobleConOrden(){inicio=null; fin=null;}

	// get/set
	void setInicio(NodoDoble inicio){this.inicio=inicio;	}
	void setFin(NodoDoble fin){this.fin=fin;	}
	NodoDoble getInicio(){return inicio;	}
	NodoDoble getFin(){ return fin;	}

	// metodos de administracion
	void agrega(Productos Producto){
		NodoDoble nuevo, auxiliar;

		//...preparar nuevo nodo ...
 		nuevo = new NodoDoble(Producto);
		nuevo.setApuntSgte(null);
		nuevo.setApuntAnt(null);

		//...adicionar nuevo nodo a la lista...
		if(inicio == null) {
			//primer nodo
			inicio = nuevo;
			fin = inicio;
		} else //Por codigo orden
                if(Producto.getCodigo().compareTo(
                    inicio.getPro().getCodigo())<0) {
                    //antes del primer nodo
                    nuevo.setApuntSgte(inicio);
                    inicio.setApuntAnt(nuevo);
                    inicio = nuevo;
                } else
                if(Producto.getCodigo().compareTo(
                    fin.getPro().getCodigo())>0 ||
			Producto.getCodigo().compareTo(
                    fin.getPro().getCodigo())==0)	{
                    //después del último nodo
                    nuevo.setApuntAnt(fin);
                    fin.setApuntSgte(nuevo);
                    fin = nuevo;
		} else {
                    //entre dos nodos ya existentes
                    auxiliar = inicio;

                    // ubica el anterior
                    while(Producto.getCodigo().compareTo(
			auxiliar.getPro().getCodigo())>0||
			Producto.getCodigo().compareTo(
			auxiliar.getPro().getCodigo())==0) {
                auxiliar = auxiliar.getApuntSgte();
            }

                    // enlaza
                    nuevo.setApuntSgte(auxiliar);
                    nuevo.setApuntAnt(auxiliar.getApuntAnt());
                    auxiliar.getApuntAnt().setApuntSgte(nuevo);
                    auxiliar.setApuntAnt(nuevo);
		}
	}
	//.....busca un codigo en la lista
	NodoDoble busca(String codigo) {
            // empieza por el primero de la lista
            NodoDoble Auxiliar = inicio;

            // mientras no sea nulo
            while(Auxiliar != null)	{
		if(codigo.equals(Auxiliar.getPro().getCodigo()))
                    return Auxiliar;// lo encontró
		else
                    Auxiliar = Auxiliar.getApuntSgte(); // pasa al siguiente
	}// fin del while
	// terminó la lista y no lo encontró
	return null;
	}
}//fin de la clase ListaDobleConOrden
La clase productos solo es una clase de seteo u getteo de valores:
public class Productos {

private  String Codigo;
    // constructor vacío
    public Productos(){ }
    // constructor que recibe un objeto con datos
    public Productos(Productos obj)
    {
        Codigo = obj.getCodigo();
    }
    public String getCodigo() {
        return Codigo;
    }
    public void setCodigo(String Codigo) {
        this.Codigo = Codigo;
    }
}
Para ejemplo de uso:
public class Principal{
static ListaDobleConOrden ldco =new ListaDobleConOrden();
Productos Productos;
public static void main(String args[]){
ldco.setInicio(null);
    Productos =new Productos();
    Productos.setDescripcion( "abc" );
    ldco.agrega(Productos);
}
}
En caso necesites buscar algo se puede usar
NodoDoble auxiliar = Principal.ldco.busca(codigo);