Listas con Recursividad e Indirección Multiple.

Indirección Multiple, Listas, y estructuras...



/* header para el manejo de listas, realizando algoritmos 
de indireccion multiple y algoritmos recursivos....

desarrollado por kellerman rivero krsloco@gmail.com
bajo licencia creative commons, 

Muestra la manera de utilizar punteros a punteros de estructuras..
y algunos detalles adicionales... 

Aunque se puede simplificar cada una de las funciones
haciendo que no devuelvan valor, he decidido dejarlas
implementadas de esa forma, con la finalidad de poder hacer
hacer asignaciones del tipo:

puntero_lista = funcion_ex(&puntero_principal,parametros...);

de forma tal, que se puede pasar el puntero principal de la 
lista sin miedo a perderlo, a la vez que la funcion retorna
una copia del puntero principal que puede ser almacenada en otra 
parte.

Puede tener errores, asi que acepto sugerencias.


CULTCA (UNELTCA) 2010... 
Kellerman Rivero

*/

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


/*funcion de inserción por el inicio
mejorada con indireccion multiple */
lista *insertar_inicio_ex (lista **inicio, int valor){
    lista *q;
    if((q = solicitar_nodo())!=NULL){
      q -> info = valor;
      q -> sig = *inicio;
      *inicio = q;
    } else printf("Memoria no Disponible \n");
    return *inicio;
}

/*funcion de eliminacion por el inicio
mejorada con indireccion multiple */
lista *eliminar_inicio_ex (lista **inicio){ 
    if (inicio != NULL){
      lista *q;
      q = *inicio;
      *inicio = (*inicio)->sig;
      free(q);
      return *inicio;
    } else return NULL;
}

/*funcion de insercion al final de la lista usando
indireccion multiple */
lista *insertar_final_ex (lista **inicio, int valor){
   if (*inicio != NULL){
     lista *q,*w; w = *inicio;
     while ( w->sig != NULL)
       w = w->sig;
     if((q = solicitar_nodo())!=NULL){
      q -> info = valor;
      q -> sig = NULL;
      w -> sig = q;
     } else printf("Memoria no Disponible \n");
     return *inicio;
   } else {
     insertar_inicio_ex(inicio,valor);
     return *inicio;
   }
}

/*Funcion de eliminacion al final de la lista 
mejorada con indireccion multiple */
lista *eliminar_final_ex (lista **inicio){
  lista *q,*w;
  if (*inicio != NULL){
    if((*inicio)->sig == NULL) eliminar_inicio_ex(inicio);
    else {
      w = *inicio; 
      while (w->sig != NULL){
  q = w;
  w = w -> sig;
      }
      q -> sig = NULL;
      free(w); 
    }
    return *inicio;
  } else return NULL;
}

/*funcion de eliminacion al final de la lista
usando recursividad (mas recursos) e indireccion multiple*/
lista *eliminar_final_rex (lista **inicio){ 
  if(*inicio != NULL){
    if((*inicio)->sig==NULL) eliminar_inicio_ex(inicio);
    else{
     if  ((*inicio)->sig->sig != NULL) {
       lista *q;
       q = (*inicio)->sig;
       eliminar_final_rex(&q);
     } else if((*inicio)->sig!=NULL) {
       free((*inicio)->sig);
       (*inicio)->sig = NULL;
     }
    }
  } else return NULL;
}

/*funcion de insercion al final de la lista
usando recursividad (mas recursos) e indireccion multiple*/
lista *insertar_final_rex(lista **inicio, int valor){ 
  if(*inicio != NULL){
    lista *q,*a;
     if((*inicio)->sig == NULL){
       if((q = solicitar_nodo())!=NULL){
            q -> info = valor;
     q -> sig = NULL;
     (*inicio)->sig =q;  
       } else {
        printf("Memoria no Disponible \n");
        return NULL;
       }
     } else {
 q= (*inicio)->sig;
       insertar_final_rex(&q,valor);
     }
  } else {
     return insertar_inicio_ex(inicio,valor);
  }
}

/*Funcion de inicializacion simple*/
lista *inicializar_ex(lista **inicio){
  *inicio = NULL;
  return *inicio;
}

lista *liberar_ex(lista **inicio){
  if (*inicio != NULL){
  while((*inicio)->sig != NULL)
    eliminar_inicio_ex(inicio);
    
    inicializar_ex(inicio);
  }
  return *inicio;
}

/*funcion de inicializacion de la lista
con n-nodos con informacion aleatoria */
lista *inicializar_random_ex(lista **inicio,int num_nodos){
  lista *q;
  if(*inicio != NULL) {liberar_ex(inicio);}
  inicializar_ex(inicio);
  srand(time(NULL));
  while(num_nodos--){
    insertar_inicio_ex(inicio,1+rand()%20);
  }
  return *inicio;
}


/*Combina dos valores, y los introduce en la lista_destino.. */
lista *combinar_valores_ex (lista** lista_destino, int valor1, int valor2){
  insertar_final_ex(lista_destino,(valor1 + valor2));
  return *lista_destino;
}

lista *fusion_nodos_regla01 (lista **lista_p, lista **lista_w){
    lista *P = *lista_p;
    liberar_ex(lista_w);
    while(P->sig != NULL){
    combinar_valores_ex(lista_w,P->info,P->sig->info);
    if (P->sig->sig != NULL){ /*si podemos desplazarnos 2 posiciones lo hacemos*/
      P = P->sig->sig;
    } else { 
      break; 
    }
  }
  if ((P->sig==NULL)) combinar_valores_ex(lista_w,P->info,0);
  return *lista_w;
}

lista *fusion_nodos_regla02 (lista** lista_p, lista** lista_w){
    lista *i,*j;
    i = j =  *lista_p;
    liberar_ex(lista_w);
    while((i->sig!=NULL)&&(j->sig!=NULL)){
      /*Si nodo->info apuntado por i es impar*/
      if(i->info%2){ 
 /*Si el siguiente del nodo apuntado por j es distinto
 de NULL, y j es impar nos seguimos desplazando hasta 
 conseguir un nodo->info apuntado por j par, o se acabe 
 la lista */
 while((j->sig!=NULL)&&(j->info%2))   
     j=j->sig;
 
 /*Al salir del ciclo mientras, preguntamos si 
 el ultimo nodo->info apuntado por j es par..
 en caso afirmativo, realizamos la fusion de nodos */
 if (j->info%2==0) //
    combinar_valores_ex(lista_w,i->info,j->info);
      }
      
      i=i->sig; /*nos seguimos desplazando con el apuntador i.*/
      if(j->sig!=NULL)j=j->sig;
    } 
    printf("Resultado: ");
    //imprimir_lista(*lista_w,0);
  return *lista_w;
}
      

void menu_ex(lista **P, lista **W){
     int r, n_nodos=0;
     do {
         system("cls");
         printf("************************************************\n");
         printf("* USANDO INDIRECCION MULTIPLE (lista **inicio) *\n");         
         printf("************************************************\n");
         printf("************************************************\n");
         printf("*1)  Inicializar Lista                         *\n");
         printf("*2)  Imprimir    Lista                         *\n");
         printf("*3)  Insertar Inicio                           *\n");         
         printf("*4)  Insertar Final                            *\n");
         printf("*5)  Insertar Final Recursivo                  *\n");                  
         printf("*6)  Eliminar Inicio                           *\n");
         printf("*7)  Eliminar Final                            *\n");         
         printf("*8)  Eliminar Final Recursivo                  *\n");         
         printf("*9)  Liberar Lista                             *\n");         
         printf("*10) Crear Fusion (SubLista) (Ejer. 01)        *\n");         
         printf("*11) Crear Fusion (SubLista) (Ejer. 02)        *\n");
         printf("*12) Menu Disponible (Ejer. XX)                *\n");   
         printf("************************************************\n");
         printf("************************************************\n");         
         printf("*    PRESIONE CERO PARA SALIR DEL PROGRAMA     *\n");
         printf("************************************************\n");
         scanf("%d",&r);
         switch(r){
                   case 1: 
                         system("cls");
                         printf("Introduzca el numero de nodos: ");
                         scanf("%d",&n_nodos);
                         inicializar_random_ex(P,n_nodos);
                         break;
                   case 2: 
                         system("cls");
                         imprimir_lista(*P,0);
                         break;
                   case 3:
                         insertar_inicio_ex(P,1+rand()%20);
                         break;
                   case 4:
                         insertar_final_ex(P,1+rand()%20);
                         break;
                   case 5:
                         insertar_final_rex(P,1+rand()%20);
                         break;
                   case 6:
                         eliminar_inicio_ex(P);
                         break;
                   case 7:
                         eliminar_final_ex(P);
                         break;
                   case 8:
                         eliminar_final_rex(P);
                         break;
                   case 9:
                         liberar_ex(P);
                         break;
                   case 10:
                         fusion_nodos_regla01(P,W);
                         break;
                   case 11:
                         fusion_nodos_regla02(P,W);
                         break;
                   default: 
                         printf("Opcion invalida \n");
         }
         
         if (r != 2) {system("cls"); imprimir_lista(*P,0);}
         if ((r > 9) && (r<12))imprimir_lista(*W,0);
         n_nodos = getch();
     } while (r =! 0);
}


Ahora el programa principal...



#include  <stdio.h>
#include  <stdlib.h>
#include  "lista.h"
//#include  "listas_normales.h"
#include  "listas_indireccion.h"
#define MODO_HORIZONTAL 0
#define MODO_VERTICAL 1

int main(){
  int n_nodos;
  lista *P,*W;
  inicializar_ex(&P);
  inicializar_ex(&W);
  menu_ex(&P,&W);
  return 0;
}

0 comentarios:

Publicar un comentario

Seguidores

Estadisticas