Powered By Blogger

sábado, 17 de septiembre de 2011

Operaciones

En una lista los elementos son contiguos en lo que concierne al enlazado.


En cambio, mientras que en un array los elementos están contiguos en la memoria, en una lista los elementos están dispersos.
El enlace entre los elementos se hace mediante un puntero.
En realidad, en la memoria la representación es aleatoria en función del espacio asignado.

El puntero siguiente del último elemento debe apuntar hacia NULL (el fin de la lista).

Para acceder a un elemento, la lista es recorrida comenzando por el inicio, el puntero siguiente permite el desplazamiento hacia el próximo elemento.
El desplazamiento se hace en una sola dirección, del primer al último elemento.
Si deseas desplazarte en las dos direcciones (hacia delante y hacia atrás) deberás utilizar las [ listas doblemente enlazadas]

B. Inserción de un elemento en la lista
A continuación el algoritmo de inserción y registro de los elementos:
  • declaración del elemento a insertar
  • asignación de la memoria para el nuevo elemento
  • rellenar el contenido del campo de datos
  • actualizar los punteros hacia el primer y ultimo elemento si es necesario.
    • Caso particular: en una lista con un solo elemento, el primero es al mismo tiempo el último.
    • Actualizar el tamaño de la lista


Para añadir un elemento a la lista hay varios casos:
  • 1. Inserción en una lista vacía
  • 2. Inserción al inicio de la lista
  • 3. Inserción al final de la lista
  • 4. Inserción en otra parte de la lista.

1. Inserción en una lista vacía
Ejemplo de la función:
int ins_en_lista_vacia (Lista *lista, char *dato);


La función devuelve 1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria para el nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero siguiente del nuevo elemento apuntará hacia NULL (ya que la inserción es hecha en una lista vacía se utiliza la dirección del puntero inicio que vale NULL)
  • los punteros inicio y fin apuntaran hacia el nuevo elemento
  • el tamaño es actualizado



La función
/* inserción en una lista vacía */
int ins_en_lista_vacia (Lista * lista, char *dato){
  Element *nuevo_elemento;
  if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
    return -1;
  if ((nuevo _elemento->dato = (char *) malloc (50 * sizeof (char)))
      == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);

  nuevo_elemento->siguiente = NULL;
  lista->inicio = nuevo_elemento;
  lista->fin = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

2. Inserción al inicio de la lista
Ejemplo de la función:
int ins_inicio_lista (Lista *lista,char *dato);


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero siguiente del nuevo elemento apunta hacia el primer elemento
  • el puntero inicio apunta hacia el nuevo elemento
  • el puntero fin no cambia
  • el tamaño es incrementado



La función
/* inserción al inicio de la lista */
int ins_inicio_lista (Lista * lista, char *dato){
  Element *nuevo_elemento;
  if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
    return -1;
  if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
      == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);

  nuevo_elemento->siguiente = lista->inicio
  lista->inicio = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

3. Inserción al final de la lista
Ejemplo de la función:
int ins_fin_lista (Lista *lista, Element *actual, char *dato);


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero siguiente del ultimo elemento apunta hacia el nuevo elemento
  • el puntero fin apunta hacia el nuevo elemento
  • el puntero inicio no cambia
  • el tamaño es incrementado



La función
/*inserción al final de la lista */
int ins_fin_lista (Lista * lista, Element * actual, char *dato){
  Element *nuevo_elemento;
  if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
    return -1;
  if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
      == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);

  actual->siguiente = nuevo_elemento;
  nuevo_elemento->siguiente = NULL;

  lista->fin = nuevo_elemento;

  lista->tamaño++;
  return 0;
}

4. Inserción en otra parte de la lista
Ejemplo de la función:
int ins_lista (Lista *lista, char *dato,int pos);


La función devuelve -1 en caso de error, si no devuelve 0.

La inserción se efectuará después de haber pasado a la función una posición como argumento.
Si la posición indicada no tiene que ser el último elemento. En ese caso hay que utilizar la función de inserción al final de la lista.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • Elegir una posición en la lista (la inserción se hará después de haber elegido la posición)
  • el puntero siguiente del nuevo elemento apunta hacia la dirección a la que apunta el puntero siguiente del elemento actual.
  • el puntero siguiente del elemento actual apunta al nuevo elemento
  • los punteros inicio y fin no cambian
  • el tamaño se incrementa en una unidad



La función
/* inserción en la posición solicitada */
int ins_lista (Lista * lista, char *dato, int pos){
  if (lista->tamaño < 2)
    return -1;
  if (pos < 1 || pos >= lista->tamaño)
    return -1;

  Element *actual;
  Element *nuevo_elemento;
  int i;

  if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL)
    return -1;
  if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
      == NULL)
    return -1;

  actual = lista->inicio;
  for (i = 1; i < pos; ++i)
    actual = actual->siguiente;
  if (actual->siguiente == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);

  nuevo_elemento->siguiente = actual->siguiente;
  actual->siguiente = nuevo_elemento;
  lista->tamaño++;
  return 0;

C. Eliminación de un elemento de la lista
A continuación un algoritmo para eliminar un elemento de la lista:
  • uso de un puntero temporal para guardar la dirección de los elementos a eliminar
  • el elemento a eliminar se encuentra después del elemento actual


Apuntar el puntero siguiente del elemento actual hacia la dirección del puntero siguiente del elemento a eliminar
  • liberar la memoria ocupada por el elemento eliminado
  • actualizar el tamaño de la lista


Para eliminar un elemento de la lista hay varios casos:
  • 1. Eliminación al inicio de la lista
  • 2. Eliminación en otra parte de la lista

1. Eliminación al inicio de la lista
Ejemplo de la función:
int sup_inicio (Lista *lista);


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • el puntero sup_elem contendrá la dirección del 1er elemento
  • el puntero inicio apuntara hacia el 2do elemento
  • el tamaño de la lista disminuirá un elemento



La función
/* eliminación al inicio de la lista */
int sup_inicio (Lista * lista){
  if (lista->tamaño == 0)
    return -1;
  Element *sup_elemento;
  sup_element = lista->inicio;
  lista->inicio = lista->inicio->siguiente;
  if (lista->tamaño == 1)
    lista->fin = NULL;
  free (sup_elemento->dato);
  free (sup_elemento);
  lista->tamaño--;
  return 0;
}

2. Eliminación en otra parte de la lista
Ejemplo de la función:
int sup_en_lista (Lista *lista, int pos);


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • el puntero sup_elem contendrá la dirección hacia la que apunta el puntero siguiente del elemento actual
  • el puntero siguiente del elemento actual apuntara hacia el elemento al que apunta el puntero siguiente del elemento que sigue al elemento actual en la lista.


Si el elemento actual es el penúltimo elemento, el puntero fin debe ser actualizado.
  • el tamaño de la lista será disminuido en un elemento




La función
/* eliminar un elemento después de la posición solicitada */
int sup_en_lista (Lista * lista, int pos){
  if (lista->tamaño <= 1 || pos < 1 || pos >= lista->tamaño)
    return -1;
  int i;
  Element *actual;
  Element *sup_elemento;
  actual = lista->inicio;

  for (i = 1; i < pos; ++i)
    actual = actual->siguiente;

  sup_elemento = actual->siguiente;
  actual->siguiente = actual->siguiente->siguiente;
  if(actual->siguiente == NULL)
          lista->fin = actual;
  free (sup_elemento->dato);
  free (sup_elemento);
  lista->tamaño--;
  return 0;
}


D. Visualización de la lista
Para mostrar la lista entera hay que posicionarse al inicio de la lista (el puntero inicio lo permitirá). Luego utilizando el puntero siguiente de cada elemento la lista es recorrida del 1ero al ultimo elemento.
La condición para detener es dada por el puntero siguiente del ultimo elemento que vale NULL.

La función
/* visualización de la lista */
void visualización (Lista * lista){
  Element *actual;
  actual = lista->inicio;
  while (actual != NULL){
      printf ("%p - %s\n", actual, actual->dato);
      actual = actual->siguiente;
  }
}

E. Destrucción de la lista
Para destruir la lista entera, he utilizado la eliminación al inicio de la lista ya que el tamaño es mayor a cero.

La función
/* destruir la lista */
void destruir (Lista * lista){
  while (lista->tamaño > 0)
    sup_inicio (lista);
}

1 comentario:

  1. ola ola chaparrita hermosa jeje lo mismo digo yo esa informacion es igualita a ala mia jojo...k bueno k estas en mi ( ekipinn) si no como le habria echooo..jum buen trabajooo nos vemos ba bae

    ResponderEliminar