¿Cómo Crear un Grafo(Lista de Adyacencia) en C? - How to Create a Graph(Adjacency List) in C?


#include<stdlib.h>

#include<string.h>

#include<math.h>

 #include<stdio.h>


//Estrucutura Lista Vertical

typedef struct Nodo{

    int valor;

    struct Nodo2 *sublista;

    struct Nodo *siguiente;

}miNodo;


//Estrucutura Lista Horizontal

typedef struct Nodo2{

    int valor;

    struct Nodo2 *siguiente;

}NodoEnlace;


void menu();


void ingresarNodosLA(miNodo**, int);

void liberar(miNodo**);

void mostrarLA(miNodo*); //lista

void mostrarEnlace(NodoEnlace*enlace);


void funcionEnlaces(miNodo*);

miNodo* buscarNodo(miNodo*lista, int valor);

void ingresarEnlace(miNodo** final, int dato);

void insertarEnlace(miNodo*, int origen, int destino);


void eliminarVertice(miNodo**);

void liberarVertice(miNodo**lista, int vertice);


int main(){

    miNodo *ListVer = NULL;

    NodoEnlace *enlaces = NULL;

    int op, valor;

    

    do{

        menu(&op);

        switch(op){

            case 1:

                

                printf("\nIngrese el Nodo: ");

                scanf("%d",&valor);

                ingresarNodosLA(&ListVer, valor);

                break;

                

            case 2:

                

                if(ListVer==NULL){ //validacion

                    printf("Primero ingrese los Nodos");

                }else{

                    funcionEnlaces(ListVer);

                }

                break;

            case 3:

               

                if(ListVer==NULL){ //validacion

                    printf("Primero ingrese los Nodos");

                }else{

                   // mostrar(ListVer); //mostramos lista

                    eliminarVertice(&ListVer);

                }

                break;

                

            case 4:

               

                if(ListVer==NULL){ //validacion

                    printf("Primero ingrese los Nodos");

                }else{

                    mostrarLA(ListVer); //mostramos lista

                    eliminarVertice(&ListVer);

                }

                break;

            case 5:

                

                if(ListVer==NULL){ //validacion

                    printf("Primero ingrese los Nodos");

                }else{

                    mostrarLA(ListVer); //mostramos lista

                }

                break;

        }

    }while(op!=6);

    liberar(&ListVer); //Liberar Memoria ListAdy

    printf(" El Programa Ha Terminado Satisfactoriamente /n ");

    return 0;

}



void menu(int *op){

    //int opcion;

    printf("1. Ingresar Vertices(ListVer)\n");

    printf("2. Ingresar Enlaces(ListHor)\n");

    printf("3. Eliminar Vetices\n");

    printf("4. Eliminar Enlaces\n");

    printf("5. Mostrar Lista de Adyacencia\n");

    printf("6. Salir\n");

    printf("Seleccione una opcion: ");

    scanf("%d",op);

}


//1

void ingresarNodosLA(miNodo** Vertical, int dato){ //Procedimiento para ingresar los nodos a la Lista Vertical

    miNodo *nuevoNodo = (miNodo*)malloc(sizeof(miNodo)); //Reservamos Memoria en el Heap

    nuevoNodo->valor = dato;  //Asignamos el dato al nodo

    nuevoNodo->siguiente = NULL; //Apuntador1 a NULL

    nuevoNodo->sublista = NULL//Apuntador2 a NULL

    if((*Vertical)==NULL){    //Si la lista Vertical esta vacia

        (*Vertical) = nuevoNodo;  //La lista vertical es igual al nuevoNodo

    }else{

        miNodo *aux=*Vertical;  //Aux apunta al primer elemento de la listavertical

        while(aux->siguiente!=NULL){

            aux=aux->siguiente;  //Recorre la Lista

        }

        aux->siguiente=nuevoNodo; //Asignamos a aux el nuevoNodo

    }

    printf("\nIngresado %d", (*Vertical)->valor); //mostrar e pantalla

}



void funcionEnlaces(miNodo*lista_Horizontal){  //Procedimiento para ingresar los enlaces(Parte1: Tener los nodos Origen y Destino de acuerdo al enlace) en la lista Vetical

    int origen, destino;

    miNodo* aux = NULL;

    miNodo*aux2 = NULL;

    do{

        aux = lista_Horizontal;

        printf("\nIngrese nodo origen: "); //(origen,destino)

        scanf("%d",&origen);

        aux = buscarNodo(aux, origen); //aux almacena el nodoOrigen

        if(aux){  //Si se encontro el nodoOrigen

            do{

                aux2 = lista_Horizontal;

                printf("\nIngrese nodo destino: ");

                scanf("%d",&destino);

                aux2 = buscarNodo(aux2, destino); //aux2 almacena el nodoDestino

                if(aux2)

                    ingresarEnlace(&aux, destino); //Ingresamos el Enlace en (nodoOrigen,nodoDestino)

        

            }while(!aux2);

        }

    }while(!aux);

}


miNodo* buscarNodo(miNodo*lista_Vertical, int valor){  //Funcion que Busca el nodo origen despues el destino en la listaVetical

    if(!lista_Vertical){

        printf("\nEl vertice no existe!\n");

        return NULL;

    }

    if(lista_Vertical->valor == valor){

        return lista_Vertical; //Retorna el nodoOrigen

    }else{

        return buscarNodo(lista_Vertical->siguiente, valor); //Usando recursividad para recorrer la listaVert

    }

}



void ingresarEnlace(miNodo** Horizontal, int dato){ //Procedimiento para ingresar los enlaces(Parte2: Crear el Nodo, enlazar principalmente con la lista vert la horizontal) en la lista Vetical


    

    NodoEnlace *nuevoNodo = (NodoEnlace*)malloc(sizeof(NodoEnlace)); //Reservamos Memoria en el Heap

    nuevoNodo->valor = dato;  //Asignamos el dato al nodo

    nuevoNodo->siguiente = NULL;

    if((*Horizontal)->sublista==NULL){ //Si el nodoOrigen su segundo apuntadorder no tiene horizontalmente

        (*Horizontal)->sublista = nuevoNodo; //Enotces asignamos el nuevoNodo

    }else{

        NodoEnlace *aux;

        aux=(*Horizontal)->sublista; //aux tiene el nodo origen

        while(aux->siguiente!=NULL){ //Recorremos la lista horizontal de ese nodoOrigen hasta encontrar el espacion para enlnzar el nuevoNodo, obviamente al utlimo de la lista

            aux=aux->siguiente;

        }

        aux->siguiente=nuevoNodo;  //Ya esta enlazado el nuevoNodo

    }

    printf("\nEnlace (%d, %d)", (*Horizontal)->valor, nuevoNodo->valor); //NodoOrigen, NodoDestino

}




void mostrarLA(miNodo*lista_Adyacencia){  //Procedimiento para mostrar la Lista de Adyacencia(Parte1: ListVertical con su Nodo)

    miNodo *aux = lista_Adyacencia; //Recorrer nodos

    printf("\n Vertices:");

    while(aux!=NULL){

        printf("\nNodo %d -> ", aux->valor);

        mostrarEnlace(aux->sublista); //Mostrar los elementos de la listaHorizontal de ese nodo

        aux = aux->siguiente; //Recorremos la listaVertical, pasamos a los otros nodos

    }

    printf("\n");

}

void mostrarEnlace(NodoEnlace*enlace){ //Procedimiento para mostrar la Lista de Adyacencia(Parte1: ListHorizontal de ese respectivo Nodo)

    

    if(enlace){

        printf(" %d", enlace->valor); //Imprimer cada valor de la listHorizontal de ese Nodo

        mostrarEnlace(enlace->siguiente); //Usando recursividad para recorrer la listHorizontal

    }

}




void eliminarVertice(miNodo**lista_Adyacencia){ //Procedimiento para Eliminar un Vetice

    

    int vertice;

    miNodo*aux = (*lista_Adyacencia); //Aux tiene el primer elemento de la listVert

    

    do{

        printf("Ingrese el Vertice a Eliminar: ");

        scanf("%d",&vertice);

        aux = buscarNodo(aux, vertice);  //Busca el NodoCorrespondiente(Vertice) igual al ingresado

        if(aux){

            liberarVertice(&(*lista_Adyacencia), vertice);  //Liberar Memoria y desenlazar

        }

    }while(!aux);

}


void liberarVertice(miNodo**lista_Adyacencia, int vertice){  //Procedimiento para Desenlazar un Vetice

    miNodo* anterior = NULL;

    miNodo* aux = (*lista_Adyacencia);

    while(aux!=NULL){

        if(aux->valor == vertice){

            anterior->siguiente = aux->siguiente; //Enlaza con el Nodo posteriro al Nodo a Eliminar

           // printf("\nLiberado vertice: %d", aux->valor);

            free(aux); //Liberamos el Nodo(Vetice)

            break;

        }

        anterior = aux; //Anteriro apunta a lo mismo que aux

        aux = aux->siguiente; //Recorremos la lista

    }

}




void liberar(miNodo**final){  //Procedimiento para Liberar Memoria de la ListAdy

    miNodo *aux = (*final);  //Aux tiene el primer elemento de la list vertical

    while(aux!=NULL){

        aux = (*final)->siguiente;

        printf("\nLiberado vertice: %d", (*final)->valor);

        free((*final));

        (*final) = aux;

    }

}



Publicar un comentario

0 Comentarios