//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Estructura.
struct nodo
{
char nombre[50];
int socio;
struct nodo *Siguiente;
struct nodo *Anterior;
struct nodo *Inicio;
struct nodo *Fin;
int tam;
};
//Prototipos de las funciones.
int insertar (struct nodo *Lista , char *n, int s);
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2);
int comparar(char *cad1,char *cad2);
void *copiar(struct nodo *Lista, char letra);
int menu (struct nodo *Lista);
void imprimir (struct nodo *Lista);
//---------------------------------------MAIN-------------------------------------------//
int main (void)
{
struct nodo *lista;
lista=malloc(sizeof(struct nodo));
char *nom;
nom=malloc(50);
int opcion=1;
int soc;
int aux;
char *str1, *str2;
char l;
char **nombres;
int i=0;
//Asignación de memoria.
str1=malloc(50);
str1=malloc(50);
//Incicialización de variables.
lista->Inicio=NULL;
lista->Fin=NULL;
lista->tam=0;
while (opcion!=4)
{
opcion=menu(lista);
switch (opcion)
{
case 4:
printf ("\nFin de la ejecución.\n");
exit(-1);
break;
case 0:
printf ("\nIngrese un nombre:");
scanf ("%s",nom);
printf ("\nIngrese nro. de socio:");
scanf ("%d",&soc);
insertar (lista,nom, soc);
imprimir(lista);
printf ("\n%d elementos.\n",lista->tam);
break;
case 1:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
intercambiar (lista,str1,str2);
imprimir (lista);
break;
case 2:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
aux = comparar (str1,str2);
if (aux==0)
printf ("\nCadenas iguales.\n");
if (aux==1)
printf ("\nPrimera cadena mayor.\n");
if (aux==-1)
printf ("\nPrimera cadena menor.\n");
break;
case 3:
printf ("\nIngrese letra:");
scanf ("\n%c",&l);
getchar();
nombres=copiar (lista,l);
printf ("\n----->");
while (*(nombres+i)!='\0')
{
printf ("%s----->",*(nombres+i));
i++;
}
}
}
return 0;
}
//---------------------------------------MENU-------------------------------------------//
int menu (struct nodo *Lista)
{
int eleccion;
if (Lista->tam==0)
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
if (eleccion==1)
eleccion=4; //Para que coincida con el menú de abajo.
}
else
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Intercambiar nodos.\n2-Comparar nodos.\n3-Copiar nodos.\n4-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
}
return eleccion;
}
//---------------------------------INSERTAR NUEVO NODO----------------------------------//
int insertar (struct nodo *Lista , char *n, int s)
{
struct nodo *Nuevo, *Actual;
int insert;
int i=0;
//Reserva memoria para el nuevo nodo.
if ( (Nuevo = malloc (sizeof (struct nodo) ) ) == NULL)
return -1;
//Recorre el nombre/cadena ingresado por el usuario.
for( i=0; *(n+i)!='\0'; i++ )
{
Nuevo->nombre[i] = *(n+i); //Y lo almacena en el nuevo nodo.
}
Nuevo->nombre[i]='\0'; //Agrega el caracter NULL al final de la cadena.
Nuevo->socio=s; //Guarda el nro. de socio ingresado en el nuevo nodo.
if (Lista->tam==0) //Si la lista está está vacía.
{
Nuevo->Anterior=Lista->Inicio;
Nuevo->Siguiente=Lista->Fin;
Lista->Inicio=Nuevo;
Lista->Fin=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
else //Inserta después del último nodo ingresado.
{
Actual=Lista->Inicio;
while ( Actual->Siguiente != NULL && strcmp(n,Actual->nombre ) !=0 )
//Mientras el elemento siguiente al nodo actual no sea NULL y el nombre ingresado por
//el usuario sea distinto al nombre del nodo actual...
Actual=Actual->Siguiente; //Salta al siguiente nodo.
Nuevo->Anterior=Actual; //El nodo anterior a 'Nuevo' es el actual.
if (Actual->Siguiente==NULL)
Lista->Fin=Nuevo;
else Actual->Siguiente->Anterior=Nuevo;
Actual->Siguiente=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
}
//------------------------------------IMPRIMIR LISTA--------------------------------------//
void imprimir (struct nodo *Lista)
{
struct nodo *Inverso, *Actual;
int choice; //Variable para elegir modo de impresión de la lista.
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n1-Imprimir lista.\n2-Imprimir lista al revés.\n");
printf ("\nOpción:");
scanf ("%d",&choice);
Actual=Lista->Inicio;
printf ("\n----->");
//Imprime desde el incio hasta el fin de la lista.
if (choice==1)
{
while (Actual!=NULL)
{
Inverso=Actual; //Cuando se termina de recorrer la lista, almacena el último nodo en 'Inverso'.
printf ("Nombre:%s/Socio:%d----->",Actual->nombre,Actual->socio); //Imprime nombre y socio del nodo.
Actual=Actual->Siguiente; //Salta al siguiente nodo.
}
}
//Imprime de atrás para delante.
if (choice==2)
{
while (Inverso!=NULL)
{
printf ("Nombre:%s/Socio:%d----->",Inverso->nombre,Inverso->socio);
Inverso=Inverso->Anterior; //Salta al nodo anterior.
}
}
}
//------------------------------------COMPARA NODOS-----------------------------------//
int comparar(char *cad1,char *cad2)
{
int i=0; //Auxiliar para recorrer cadenas.
while ( (*(cad1+i)!='\0') || (*(cad2+i)!='\0') )
{
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
i++;
}
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
else if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
return 0; //Retorna la variable aux.
}
//------------------------------------INTERCAMBIA NODOS-------------------------------//
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2)
{
struct nodo *Actual, *T1, *T2, *Aux1, *Aux2;
int i=0; //Variable auxiliar para recorrer cadenas.
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena1)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux1=Actual; //Guarda el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el primer nodo fue encontrado...
if (Aux1!=NULL)
{
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena2)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux2=Actual; //Guarda todo el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el segundo nodo fue encontrado...
if (Aux2!=NULL)
{
//Si el primer nodo es el primer elemento...
if (Aux1==Lista->Inicio)
{
//Muevo el segundo nodo al inicio de la lista.
Lista->Inicio=Aux2;
Aux2->Anterior->Siguiente=Aux1;
}
//Si el segundo nodo es el primer elemento...
else if (Aux2==Lista->Inicio)
{
//Muevo el primer nodo al inicio de la lista.
Lista->Inicio=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Si ninguno de los dos nodos hallados es el primer elemento de la lista.
else
{
Aux2->Anterior->Siguiente=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Almaceno el puntero que apunta al nodo anterior del primer nodo en una variable
//temporal.
T1 = Aux1->Anterior;
//Muevo el puntero que apunta al nodo anterior del segundo nodo al primer nodo.
Aux1->Anterior = Aux2->Anterior;
//Almaceno el puntero que apunta al nodo siguiente del primer nodo en una variable
//temporal.
T2 = Aux1->Siguiente;
//Si el primer nodo no es el último elemento...
if (Aux1!=Lista->Fin)
Aux1->Siguiente->Anterior=Aux2;
//Si es el último elemento...
Aux1->Siguiente=Aux2->Siguiente;
//Muevo el puntero que apunta al nodo anterior del primer nodo al segundo nodo.
Aux2->Anterior = T1;
//Si el segundo nodo no es el último elemento...
if (Aux2==Lista->Fin)
Aux2->Siguiente->Anterior=Aux1;
//Si es el último elemento...
Aux2->Siguiente=T2;
}
return Lista->Inicio; //Retorna el lo apuntado por el inicio de la lista.
}
else return NULL; //Retorna NULL si uno de los nodos no fue encontrado.
}
//-------------------------------------ARRAY DE NODOS---------------------------------//
void *copiar(struct nodo *Lista, char letra)
{
struct nodo *Actual;
int i=0; //Variable auxiliar para recorrer el array de punteros.
char **p; //Array de punteros, almacena los nombres que empiecen con la
//letra ingresada por el usuario.
char **pnom;
p = malloc (50*sizeof(char *));
Actual=Lista->Inicio; //Parte desde el primer elemento de la lista.
while (Actual!=NULL) //Mientras no llegue al final de la lista...
{
if (Actual->nombre[0] == letra) //Si la primera letra del nombre del nodo que se
//está analizando es igual a letra...
{
p[i]=Actual->nombre; //Se guarda el nombre del nodo en un array de punteros.
i++; //Incrementa la posición del array de punteros en 1.
}
Actual=Actual->Siguiente; //Nos corremos al siguiente nodo.
}
pnom = realloc(p,i*sizeof(char *));
return pnom;
}