Mostrando entradas con la etiqueta punteros. Mostrar todas las entradas
Mostrando entradas con la etiqueta punteros. Mostrar todas las entradas

jueves, 1 de septiembre de 2011

Ordenación (método MergeSort)

Profundizando un poco más en el tema de los algoritmos de ordenación y después de ver unos videos disponibles en la página web del MIT  he programado el algoritmo MergeSort utilizando listas enlazadas con punteros. Este algoritmo se comporta mucho mejor que el de selección cuando el número de elementos a ordenar crece. La idea que aplica este algoritmo es la de "divide y vencerás" y lo hace de modo recursivo.

struct tipo_dato {
    int num;
    struct tipo_dato *sig;
};



struct tipo_dato *mergeSort(struct tipo_dato *lista) {
    struct tipo_dato *lista1=NULL, *lista2=NULL, *listaOrd1=NULL, *listaOrd2=NULL, *listaOrd=NULL;


    if (longitud_lista(lista) <= 1) {
        return lista;
    }
    else {
        //Este es el puntero a la primera mitad de la lista.
        lista1 = lista;
        //Obtenemos la segunda parte de la lista (la segunda mitad).
        lista2 = obtener_lista2(lista);
        //Ordenamos recursivamente cada mitad del algoritmo
        listaOrd1 = mergeSort(lista1);
        listaOrd2 = mergeSort(lista2);

        //Mezclamos las dos mitades ordenadas previamente
        listaOrd = mezclar(listaOrd1, listaOrd2);

        return listaOrd;
    }
}

Para ver el código de un ejemplo de uso del algoritmo y los resultados de la ejecución podéis visitar este enlace en Codepad:
http://codepad.org/B3EOCoi8

Ordenación (método de selección)

Hemos estado hablando sobre los algoritmos de ordenación en clase y tuvimos que implementar el algoritmo de ordenación por selección para poder mostrar unos listados de datos ordenados en una aplicación que estamos realizando. A continuación muestro el código correspondiente a la función que realiza la tarea de la ordenación y la definición de la estructura de datos que representa los nodos de la lista enlazada.
struct tipo_lista_libro {
    char titulo[20];
    char autor[25];
    float precio;
    struct tipo_lista_libro *sig;
};


struct tipo_lista_libro *ordenar_lista_libros_seleccion(struct tipo_lista_libro *lista) {
    struct tipo_lista_libro *lista_aux = NULL, *lista_aux2 = NULL;
    struct tipo_lista_libro libro;

    lista_aux = lista;
    if (lista != NULL) {
        while (lista_aux->sig != NULL) {
            lista_aux2 = lista_aux->sig;
            while (lista_aux2 != NULL) {
                if (strcmp(lista_aux->titulo, lista_aux2->titulo)>0) {
                    //Copiamos el contenido de lista_aux a una variable temporal
                    strcpy(libro.titulo, lista_aux->titulo);
                    strcpy(libro.autor, lista_aux->autor);
                    libro.precio = lista_aux->precio;
                    //Copiamos el contenido de lista_aux2 a lista_aux
                    strcpy(lista_aux->titulo, lista_aux2->titulo);
                    strcpy(lista_aux->autor, lista_aux2->autor);
                    lista_aux->precio = lista_aux2->precio;
                    //Copiamos en lista_aux2 el contenido de la variable auxiliar
                    strcpy(lista_aux2->titulo, libro.titulo);
                    strcpy(lista_aux2->autor, libro.autor);
                    lista_aux2->precio = libro.precio;
                }
                lista_aux2 = lista_aux2->sig;
            }
            lista_aux = lista_aux->sig;
        }
    }
    return lista;
}

Para ver el resultado de una prueba de la ejecución de este programa visita el siguiente enlace:
http://codepad.org/qkNxYv08 en Codepad. Allí podéis ver el código completo y los resultados de la ejecución.

jueves, 11 de agosto de 2011

Listas enlazadas

Estos últimos días he estado tratando de recordar el funcionamiento de los punteros en C. Al principio me costó un poco, y cometí muchos de los errores que solía cometer cuando los descubrí hace años durante mis primeras incursiones en la programación (en C, en particular). De todos modos, creo que ya he vuelto a entender la esencia de los mismos y para comprobar mis progresos he realizado unas pruebas creando una lista enlazada y realizando ciertas operaciones básicas sobre ella (añadir elementos, eliminar, buscar y listar los elementos). El código correspondiente se puede ver a continuación.

#include <stdio.h>
#include <stdlib.h>

//Definición de los elementos de la lista
 struct list {
    int valor;
    struct list *sig;
};
typedef struct list item;

//Prototipos de funciones
int long_lista(item *lista);
item *add_lista(item *lista, int valor);
item *del_lista(item *lista, int valor);
int search_lista(item *lista, int valor);
void print_lista(struct list *lista);

int main()
{
    item *lista, *item1, *item2, *item3;
    int tamano=0;
    int i=0;

    lista=NULL;
    for (i=0; i<10; i++) {
        //Añadimos elementos a la lista
        lista = add_lista(lista,i);
    }
    printf("La longitud de la lista es: %d\n",long_lista(lista));
    printf("Antes de borrar: \n");
    //Mostramos el contenido de la lista
    print_lista(lista);
    //Borramos un elemento de la lista
    lista = del_lista(lista,9);
    printf("Despues de borrar: \n");
    //Mostramos los elementos de la lista
    print_lista(lista);

    //Búsqueda de elementos en la lista
    if (search_lista(lista,4)) printf("La lista contiene un 4\n");
    else printf("La lista no contiene un 4\n");
    if (search_lista(lista,9)) printf("La lista contiene un 9\n");
    else printf("La lista no contiene un 9\n");
    return 0;
}

/*
    Esta función devuelve el número de elementos que contiene la lista que
    recibe como parámetro
*/
int long_lista(item *lista) {
    int lon=0;

    if (lista==NULL) return 0;
    else {
        while (lista!=NULL) {
            lista=lista->sig;
            lon++;
        }
        return lon;
    }
}

/*
    Esta función devuelve un puntero al inicio de la lista después de añadirle un
    nuevo elemento cuyo valor se le pasa como parámetro a la función.
*/
item *add_lista(item *lista, int valor) {
    item *lista_aux;

    lista_aux = (item *)malloc(sizeof(item));

    if (lista==NULL) {
        lista_aux->valor=valor;
        lista_aux->sig=NULL;
        lista=lista_aux;
    }
    else {
        lista_aux->valor=valor;
        lista_aux->sig=lista;
        lista=lista_aux;
    }

    return lista;
}

/*
    Esta función devuelve un puntero a la cabeza de la lista resultante de eliminar
    el elemento cuyo valor asociado coincide con el que se pasa por parámetro.
*/
item *del_lista(item *lista, int valor) {
    item *index;
    item *temp;

    index = lista;
    if (index != NULL) {
        if (index->valor==valor) {
            index=index->sig;
            lista=index;
            return lista;   //hemos borrado el primer elemento de la lista
        }
        else {
            temp=lista;
            index=lista->sig;
            while (index!=NULL) {
                if (index->valor==valor) {
                    temp->sig=index->sig;
                    return lista;  //eliminamos de la lista el primer elemento encontrado
                }
                else {
                    index=index->sig;
                    temp=temp->sig;
                }
            }
        }
    } else
        return lista;  //no se ha borrado nada de la lista porque estaba vacía
}

/*
    Esta función devuelve un 0 si no encuentra ningún elemento en la lista cuyo valor
    asociado coincida con el pasado por parámetro, y un 1 si encuentra al menos un
    elemento cuyo valor si coincida.
*/
int search_lista(item *lista, int valor) {
    item *index;
    int encontrado=0;

    index=lista;
    while (index!=NULL) {
        if (index->valor==valor) {
            return 1;
        }
        else {
            index=index->sig;
        }
    }
    return 0;
}

/*
    Esta función se ocupa de mostrar por pantalla el valor de todos los elementos
    pertenecientes a la lista que se pasa por parámetro.
*/
void print_lista(item *lista) {
    item *index;

    index=lista;
    while (index!=NULL) {
        printf("Valor: %d\n", index->valor);
        index=index->sig;
    }
}