25
5: Listas 1 ELO320 Estructuras de Datos y Algoritmos Listas Tomás Arredondo Vidal Este material está basado en: Robert Sedgewick, "Algorithms in C", (third edition), Addison-Wesley, ISBN 0-201-31663-3. 2001 material del curso ELO320 del Prof. Leopoldo Silva material en el sitio http://es.wikipedia.org

ELO320 Estructuras de Datos y Algoritmos Listas …profesores.elo.utfsm.cl/~tarredondo/info/datos-algoritmos/ELO-320... · 5: Listas 1 ELO320 Estructuras de Datos y Algoritmos Listas

  • Upload
    trandat

  • View
    229

  • Download
    0

Embed Size (px)

Citation preview

5: Listas 1

ELO320 Estructuras de Datos y Algoritmos

Listas

Tomás Arredondo Vidal

Este material está basado en:

Robert Sedgewick, "Algorithms in C", (third edition), Addison-Wesley, ISBN 0-201-31663-3. 2001 material del curso ELO320 del Prof. Leopoldo Silva material en el sitio http://es.wikipedia.org

5: Listas 2

5-Listas

5.1 Definiciones y operaciones5.2 Listas simplemente enlazadas5.3 Listas doblemente enlazadas5.4 Listas circulares5.5 Listas auto organizadas y ordenadas

5: Listas 3

Definiciones y operaciones

Cada elemento o nodo se representa por una estructura, cuyos campos pueden ser leídos y escritos a través de un puntero a la estructura.

Suele existir un campo que se denomina clave, que identifica únicamente al nodo. La clave puede ser numérica o alfanumérica.

Operaciones posibles sobre listas incluyen: Recorrer Buscar Seleccionar Insertar Descartar

5: Listas 4

5-Listas

5.1 Definiciones y operaciones5.2 Listas simplemente enlazadas5.3 Listas doblemente enlazadas5.4 Listas circulares5.5 Listas auto organizadas y ordenadas

5: Listas 5

Listas simplemente enlazadas Listas que requieren un solo

enlace (puntero) entre un nodo y su sucesor

Elementos se direccionan en tiempo constante O(1), los elementos tienen un costo de acceso de O(n) en el peor caso

Las operaciones deben considerar que estas listas pueden estar vacías lo cual requiere un tratamiento especial

El uso de un centinela simplifica las operaciones al hacer que todos los nodos sean tratados de forma igual

5: Listas 6

Ejemplo: Lista simplemente enlazadatypedef struct moldenodo

{

int clave;

struct moldenodo *proximo;

} nodo, *pnodo;

pnodo CreaNodo(int dato)

{ pnodo pn=NULL;

if ( (pn= (pnodo) malloc(sizeof(nodo))) ==NULL) exit(1);

else

{ pn->clave=dato;

pn->proximo=NULL;

}

return(pn);

}

pnodo lista=NULL;

pnodo listaC = CreaNodo(0);

5: Listas 7

Ejemplo: Recorrer la lista y contar nodos int LargoLista(pnodo p)

{ int numeroelementos = 0;

while (p != NULL)

{

numeroelementos ++;

p = p ->proximo; //recorre la lista

}

return (numeroelementos);

}

int LargoLista(pnodo p)

{ int numeroelementos = 0;

for ( ; p != NULL; p=p->proximo) numeroelementos ++;

return (numeroelementos);

}

5: Listas 8

Ejemplo: Buscar un nodopnodo Buscar(pnodo p, int valor)

{ while (p != NULL)

{

if (p->clave== valor)

return (p); //lo encontró

else p = p ->proximo; //recorrer: O(n)

}

return (p); //retorna NULL si no lo encontró.

}

Como usar esta función?

pnodo q;

if ( (q= Buscar(lista, 5)) == NULL)

{ /* no encontró nodo con clave = 5*/

}

else

{ /* lo encontró. …..*/

}

if ( (q= Buscar(listaC->proximo, 5)) == NULL)

{ /* no encontró nodo con clave = 5*/

}

else

{ /* lo encontró. …..*/

}

5: Listas 9

Ejemplo: Seleccionar un valor extremo (mínimo)pnodo SeleccionarMinimo(pnodo p)

{ int min; pnodo t;

if (p==NULL) return (NULL);

else

{ min=p->clave; //Inicia min

t=p;

p=p->proximo;

}

while (p != NULL)

{ if (p->clave <min )

{ min=p->clave;

t=p;

}

p = p ->proximo; //recorre la lista. O(n)

}

return (t);

}

5: Listas 10

Ejemplo: Buscar el último nodo

pnodo ApuntarAlFinal(pnodo p) // como programar?

{

pnodo t;

if (p==NULL)

{

return (NULL);

}

else while (p != NULL)

{

t=p;

p = p ->proximo; //recorre la lista. O(n)

}

return (t);

}

5: Listas 11

Listas: inserción Hay dos variables de tipo puntero a

nodo: p apunta a un nodo de una lista y n apunta a un nodo correctamente inicializado (e.g. retorno de CreaNodo).

El nodo apuntado por n puede ser insertado después del nodo apuntado por p usando:

n->proximo = p->proximo; Para completar la lista se usa:

p->proximo = n; Como seria el diagrama final?

5: Listas 12

Ejemplo: insertar después Si el argumento posición toma valor

NULL, se producirá un error, por eso se verifica su existencia,

pnodo InsDespues( pnodo posicion,

pnodo nuevo)

{

if (nuevo == NULL)

return (NULL);

if (posicion != NULL)

{ nuevo->proximo = posicion->proximo;

posicion->proximo=nuevo;

return (posicion);

}

return(nuevo);

}

Ejemplo de uso:pnodo lista=NULL; //inicializar lista

pnodo pos=NULL;

lista=InsDespues(pos, CreaNodo(1));

pos =Buscar(lista, 1);

InsDespues(pos, CreaNodo(2));

pos =Buscar(lista, 2);

InsDespues(pos, CreaNodo(3));

pos =Buscar(lista, 2);

InsDespues(pos, CreaNodo(4));

5: Listas 13

Listas: inserción antes Si se desea insertar antes de la posición p; se

requiere una variable temporal para efectuar el intercambio (i.e. temp) :pnodo p = NULL; //inicializar lista

p = InsDespues(p,CreaNodo(1));

InsDespues(p,CreaNodo(2));

pnodo n = CreaNodo(3);

// Como es el diagrama?

int temp;

n->proximo = p->proximo;

p->proximo = n;

temp=p->clave;

p->clave=n->clave;

n->clave=temp;

// Como es el diagrama final?

p

1 2

3

n

5: Listas 14

Listas: inserción al final Si se desea insertar al final:pnodo InsertaNodoalFinal(pnodo posicion, int dato) { pnodo temp=posicion;

if (temp != NULL) { while (temp->proximo !=NULL)

temp=temp->proximo; //O(n) temp->proximo=CreaNodo(dato); return (temp->proximo); //retorna NULL si no se pudo crear} else return (CreaNodo(dato));

} // Ejemplo uso?

5: Listas 15

Inserción: cabeza y cola Usando variables globales

cabeza y cola:static pnodo cabeza=NULL; static pnodo cola=NULL;

pnodo insertainicio(int clave) { pnodo t=CreaNodo(clave); if(cabeza==NULL) cola=t; t->proximo=cabeza; cabeza=t; //O(1)

return(t); }

Insertafinal( )?

pnodo insertafinal(int clave)

{ pnodo t =CreaNodo(clave); if(cola==NULL) { cola=cabeza=t;}

else {

cola->proximo=t; cola=t;} //O(1)

return(t);

}

5: Listas 16

Inserción con referencias Usando referencias:void ins_nodo_ref(pnodo *p, pnodo t)

{ if (*p==NULL)

*p=t; //inserta en lista vacía.

else {

t->proximo=*p; //lee var. externa.

*p=t; //escribe en var. externa.

}

}

Uso?:

pnodo lista1=NULL;

Insertanodo_ref(&lista1, CreaNodo(4));

Insertanodo_ref(&lista1, CreaNodo(3));

Insertanodo_ref(&lista1, CreaNodo(2));

Insertanodo_ref(&lista1, CreaNodo(1));

5: Listas 17

Listas: descarte La variable p apunta al nodo

anterior al que se desea descartar, t apunta al nodo que se desea

desligar de la lista después de ejecutada la acción:

t=p->proximo; Para mantener la lista ligada:

p->proximo = t->proximo; Después se libera el espacio del

nodo descartado:free(t);

t=NULL;

5: Listas 18

5-Listas

5.1 Definiciones y operaciones5.2 Listas simplemente enlazadas5.3 Listas doblemente enlazadas5.4 Listas circulares5.5 Listas auto organizadas y ordenadas

5: Listas 19

Listas doblemente enlazadas Estas listas requieren dos

enlaces (punteros) entre un nodo, su sucesor y su antecesor:

typedef struct moldecelda

{ int clave;

struct moldecelda *nx; //next struct struct modecelda *pr; // previous

} nodo, *pnodo;

5: Listas 20

Listas doblemente enlazadas: insertar después

Diagramas muestran las variables antes de insertar el nodo apuntado por q a la lista dada por p.

Como seria el código para insertar?q->nx = p->nx; q->pr = p; p->nx = q ; q->nx->pr = q;

Como seria descartar el nodo q? q->pr->nx = q->nx; q->nx->pr = q->pr; free(q);

5: Listas 21

Listas doblemente enlazadas: condiciones

Las operaciones de insertar, buscar y descartar deben considerar las condiciones en los bordes, y que la lista pueda estar vacía.

Una forma usual de tratar simplificadamente las condiciones de borde, es definir un nodo vacío, denominado cabecera o centinela.

5: Listas 22

5-Listas

5.1 Definiciones y operaciones5.2 Listas simplemente enlazadas5.3 Listas doblemente enlazadas5.4 Listas circulares5.5 Listas auto organizadas y ordenadas

5: Listas 23

Listas circulares En listas simplemente enlazadas, sin o con cabecera,

puede escogerse que el último nodo apunte al primero, con esto se logra que el primer nodo pueda ser cualquier nodo de la lista.

La inserción al inicio, en el caso de la figura debe tratarse de manera especial, con costo O(n), para que el último nodo apunte al nuevo primero.

Si la lista es con centinela, y si el último apunta al centinela, no es necesario introducir código adicional.

5: Listas 24

5-Listas

5.1 Definiciones y operaciones5.2 Listas simplemente enlazadas5.3 Listas doblemente enlazadas5.4 Listas circulares5.5 Listas auto organizadas, ordenadas

5: Listas 25

Listas auto organizadas y ordenadas En listas auto organizadas la operación buscar

mueve a la primera posición el elemento encontrado. De esta manera los elementos más buscados van

quedando cerca del inicio. En listas ordenadas se mantienen los nodos

ordenados según el orden de las claves. Se puede tratar las listas en base a arreglos.

Pudiendo ser éstos: arreglos de nodos, en los cuales se emplean punteros; o bien arreglos que contienen la información de vínculos en base a cursores que almacenan índices.