Ejercicios_Resueltos_Listas

download Ejercicios_Resueltos_Listas

of 8

description

ejercicios sobre listas en lenguaje C

Transcript of Ejercicios_Resueltos_Listas

  • ListasImplemente la funcin List*SumaProducto(List *A,List*B) que recibe dos listas A y B, con las cuales realiza operaciones de producto y suma cuyos resultados van a formar parte de una tercera lista a retornar.Ejemplo sean las listas A y BA:

    B:

    Operaciones a realizar:Nodo 1: 2*3 + 2*0 + 2*2 + 2*1 + 2*4= 20Nodo 2: + 3*0 + 3*2 + 3*1 + 3*4= 21Nodo 3: + 1*2 + 1*1 + 1*4= 7Nodo 4: 2*1 + 2*4= 10Nodo 5: 4*4= 16Resultado de SumaProducto:C:

    Nota: Asuma que A y B son de iguales dimensionesSolucin:Note que el problema ya nos dice el prototipo de la funcin el cual no lo podemos variar:List*SumaProducto(List*A,List*B);Observe tambin que ya posee las referencias a las dos listas A y B, sobre las cuales vamos a trabajar. Recuerde tambin que cada elemento de la lista almacena un entero.Nuestro objetivo es generar una nueva lista, la lista C, en donde cada elemento de esta estar en funcin de dos listas iniciales, la lista A y la lista B. El problema explica claramente como sern generados los nuevos elementos, el cual detallaremos a continuacin:El primer elemento de la lista A (2) se multiplica por el primer elemento de la lista B (3), tambin para los elementos restantes(0,2,1,4),sumamos cada uno de estos resultados y as obtenemos el valor del primer elemento de la lista C (20)Luego el segundo elemento de la lista A (3) se multiplica por el segundo elemento de la Lista B (0), y tambin por los siguientes (2,1,4), se suma cada uno de estos resultados y as obtenemos el valor del segundo elemento en la lista C (21).Hacemos esto hasta el final de las listas. Recordar que A y B son del mismo tamao.Es importante tener bien claro como se generan los nmeros para as poder implementar un algoritmo que resuelva el problema.En el cdigo que vera a continuacin podr ver mas claramente en que consiste la solucinCdigo:List *sumaProducto(List *A,List *B){ List *C=listNew(); NodeList *iterator=NULL; NodeList *viajero=NULL; NodeList *tmp=NULL; int x,y; viajero=listGetHeader(B);//tambin podemos haber declarado viajero= B->header for(iterator=listGetHeader(A);iterator!=NULL;iterator=nodeListGetNext(iterator)){ int cont=0;//esta variable almacenara el valor del nuevo elemento de C//en cada iteraccion debe ser cero ya que en cada iteracin guardaremos un nuevo valor for(tmp=viajero;tmp!=NULL;tmp=nodeListGetNext(tmp)){ x=integerGet(nodeListGetCont(iterator)); y=integerGet(nodeListGetCont(tmp));

  • cont=x*y+cont;//guarda el valor que se almacenara en la lista C } viajero=nodeListGetNext(viajero); listAddNode(C,nodeListNew(integerNew(cont))); } return C;}Con la referencia al primer elemento de A, iteramos la lista B, generamos el valor que se almacenara en C y lo agregamos a dicha lista.

    Tome en cuenta la linea de cdigo viajero=nodeListGetNext(viajero).

    Al tomar el segundo elemento de A, volveremos a iterar la lista B, pero ya no desde el primer elemento de A sino desde el segundo, nuevamente generamos el valor que se almacera en C y lo agregamos a la lista.En la siguiente iteracin, tomamos el tercer elemento de A, volveremos a iterar la lista B, pero ya no desde el segundo sino desde el tercero nuevamente generamos el valor que se almacera en C y lo agregamos a la lista.Hacemos esto hasta el final de la lista A.

    Implemente una funcin listaInterceccion que dadas dos listas que representan dos conjuntos de elementos del mismo tipo, generar otra lista interseccin que contenga los elementos en comn que tienen estas dos listas. List *listInterseccion(List *L,List *M,cmpfn comparar){ NodeList *iterator=NULL, *traveler=NULL; Generic a; List *C=listNew(); for(iterator=listGetHeader(L);iterator!=NULL;iterator=nodeListGetNext(iterator)){ for(traveler=listGetHeader(M);traveler!=NULL;traveler=nodeListGetNext(traveler)){ if(comparar(iterator->cont,traveler->cont)==0){ a=nodeListGetCont(traveler); listAddNode(C,nodeListNew(a)); } } } return C;}

    Implemente la funcin listaRemoverRepetidos que dada una lista remueva los elementos repetidos de ella. Cree un programa que genere una lista de enteros repetidos y pruebe la funcin que ha implementado void listaRemoverRepetidos(List *L,cmpfn fn){ NodeList *iterator=NULL,*tmp=NULL,*traveler=NULL; for(iterator=listGetHeader(L);iterator!=NULL;iterator=nodeListGetNext(iterator)){ for(traveler=nodeListGetNext(iterator);traveler!=NULL;traveler=nodeListGetNext(traveler)){ if(fn(nodeListGetCont(iterator),nodeListGetCont(traveler))==0){ tmp=traveler->next; listRemoveNode(L,traveler);

  • traveler->next=tmp; } } }}

    int main() { List *A=listNew(); int i=0; //Creamos una lista de enteros con nodos repetidos para probar la funcion que hemos implementado for(i=0;icont,buscado->cont)==0){ encontrado=header; return encontrado; }else{ encontrado=buscarEnLista(header->next,buscado,comparar); } return encontrado;}

    Implemente la funcin ListConcat que, dadas dos listas, concatene los elementos de la segunda a la primera.

    void

    ListConcat(List*A,List*B){ NodeList*it=NULL; for(it=listGetHeader(B);it!=NULL;it=nodeListGetNext(it)){//Empezamos a iterar la lista B desde el principio listAddNode(A,nodeListNew(it->cont));//Agregamos el contenido de it a un nuevo nodo, que se aadira a la lista A

  • }}

    Implementar dos funciones complementarias a las listas:a) Insertar ordenadamente los elementos de una lista (no est ordenada) en otra lista (que ya est ordenada), la lista final no debe tener elementos repetidos.b) Dada una lista generar otra lista con los elementos repetidos.a) Para resolver este problema debemos tener en cuenta lo siguiente.- En un principio tendremos dos listas, la Lista A que no esta ordenada, y la Lista B que ya posee un orden en especial. Observe que usted no sabe que tipo de dato se encuentra dentro de las listas, ni tampoco el tipo de ordenamiento. Entonces nuestra funcin debe estar en la capacidad de ordenar cualquier lista que contenga cualquier TDA, es decir la funcin debe ser lo mas genrica posible. Para esto usaremos una funcion CallBack (cmpfn compare).compare(a,b) retornara cero si a y b son iguales, 1 si a>b, y -1 si acont,compare);//busca el elemento que almacena it en la lista B if(newNode==NULL){ //si el elemento buscado no se encuentra procedemos a insertar en donde corresponda newNode=nodeListNew(it->cont); //newNode es el nodo a insertar if(compare(newNode->cont,min->cont)==-1){ //insercin al principio de la Lista B nodeListSetNext(newNode,min);

  • B->header=newNode; }else{ if(compare(newNode->cont,max->cont)==1){ //insercin al final de la Lista B nodeListSetNext(max,newNode); B->last=newNode; }else{ while(min!=NULL){ //insercin en el medio de la Lista B

    //buscamos la posicin correcta para insertar min=min->next; if(compare(newNode->cont,min->cont)==-1){ prev=listGetPrevious(B,min);

    // Recuerde que la funcin listGetPrevious nos retorna un puntero al elemento previo de la variable min nodeListSetNext(newNode,min); nodeListSetNext(prev,newNode); break; } } } } } }}No olvide definir la funcin de comparacin que se ajuste al tipo de dato que almacenan las listas. Supongamos que estos son enteros, entonces tendremos.int compare(Generic a,Generic b){

    int x=integerGet(a);int y=integerGet(b);if(x==y)return 0;if(x>y)return 1;return -1;

    }Antes de seguir con el siguiente literal. Piense en el siguiente problema. Suponga que las listas almacenan el tipo de dato CuentaBancaria , y se desea que el tipo de ordenamiento sea con respecto al saldo de cada cuenta bancaria. Recuerde que asumimos tambin que el orden seria de menor a mayor. Ademas se le proporciona la siguiente informacin:typedef struct CuentaBancaria{ int ID; char propietario[20]; double saldo;}CuentaBancaria;CuentaBancaria*cuentaBancariaGet(Generic a);//permite recuperar la cuenta bancaria almacenada en una variable GenericQue hara falta implementar para resolver el problema?La respuesta es sencilla, solo tendramos que plantear una funcin que compare cuentas bancarias.int compare(Generic a,Generic b){ CuetaBancaria c1=cuentaBancariaGet(a); CuentaBancaria c2=cuentaBancariaGet(b); if(c1->saldo==c2->saldo)return 0; if(c1->saldo>c2->saldo)return 1; return -1;}b)Antes de pensar en la implementacin primero definamos el prototipo de la funcin. Esta vez el problema nos dice implcitamente cual sera el modelo de la funcin. Primero que recibiremos una

  • variable lista como parmetro a la cual le vamos a invertir sus elementos. Segundo nuestra funcin debe devolver otra lista. Entonces tendremos: List*invertirLista(List*L);La implementacin consiste en remover el ultimo elemento de la lista enviada por parmetro, agregarla en la lista nueva, hacer esto hasta que la lista inicial este vaca. Al final retornamos la lista invertida.List *invertiLista(List *L){ NodeList *iterator; List *invertida=listNew(); NodeList *tmp; while(!listIsEmpty(L)){ iterator=listGetLast(L); tmp=listRemoveLast(L); listAddNode(invertida,tmp); } return invertida;}

    Sea el TDA:typedef struct { List* l_ordenada; Orden orden; }PriorityQueue;Donde Orden es un tipo de datos enumeracin cuyos valores son ASC Y DES, que representa el tipo de ordenamiento de los elementos en la cola y l_ordenada representa una lista ordena.Implemente el comportamiento:priorityQueueEnqueue(PriorityQueue *Q,NodeList *newNode,fnCmp compare) El cual inserta un nuevo nodo en la ubicacin que le corresponde de acuerdo al tipo de ordenamiento de la cola. El parmetro compare representa una funciona de CallBack que recibe dos parmetros que son los contenidos de los nodos a comparar y retorna 0 si son iguales, -1 si el primero es menor que el segundo y 1 si el primero es mayor que el segundo.Tenga en cuenta lo siguiente:Cuando la lista esta vaca, simplemente insertamos el nodo como nico elemento de la lista.El procedimiento debe estar en funcin del tipo de ordenamiento de la cola. Sabemos que la funcin compare retorna 1 si el primer elemento es mayor que el segundo, orden descendente(DES). Compare retorna -1 si el primer elemento es menor que el segundo, orden ascendente(ASC).Existen tres tipos de inserciones, al inicio de la lista, en medio de la lista, y al final de la lista.Inicio de la lista: Sabemos que el primer elemento de la lista sera el mayor en un orden descendente. Si el nuevo nodo es mayor que el mayor de todos los elementos ya ingresados, entonces el nuevo nodo se inserta al inicio, caso similar ocurre en el orden ascendente.En el medio de la lista: Comparamos cada elemento de la lista con el nuevo nodo, de esta forma encontraremos la posicin exacta en donde insertar.Final de la lista: Si no se inserto al inicio, ni en el medio, agregamos el nuevo nodo al final de la lista.

    El siguiente cdigo resuelve el problema, lalo detenidamente y pruebe que este funciona como debera.

    Cdigo:typedef enum orden{ ASC, DES} Orden;

    int orden(Orden orden) { if (orden == 0) {//si el orden es ASC retornamos -1

  • return -1; }else{//si el orden es DES retornamos 1 return 1; }}

    void priorityQueueEnQueue(PriorityQueue *Q, NodeList *newNode, cmpfn compare) { NodeList* it, * tmp; List *L=Q->l_ordenada; if (listIsEmpty(Q->l_ordenada)) { listAddNode(Q->l_ordenada, newNode); return; } it = listGetHeader(L); if (compare(newNode->cont, it->cont) == orden(Q->orden)) { listAddFirst(L, newNode);//insertar al principio de la lista return; } for (it = listGetHeader(L); it != NULL; it = it->next) { if (compare(newNode->cont, it->cont) == orden(Q->orden)) { tmp = listGetPrevious(Q->l_ordenada, it); listAddNext(Q->l_ordenada, tmp, newNode);//inserta en el medio return; } } listAddNode(Q->l_ordenada, newNode);//inserta al final return;}

    Implemente la funcin List_RemoveLastOcurrence (o Lista_RemoverUltimaOcurrencia) que, dada una lista con posibles elementos repetidos, remueva el ltimo nodo que contiene a un elemento indicado. Como ejemplo ilustrativo, considere la siguiente lista de Personas:L

    List_RemoveLastOcurrence (L, , )L

    Observe que el problema le da la facilidad de escoger los parametros y el tipo de dato de retorno. Usaremos una funcion callBack para facilitar el trabajo, podemos definir el prototipo de la funcion de la siguiente forma: void List_RemoveLastOcurrence(List*L,NodeList*element,cmpfn comparable);Recuerde que comparable(a,b) devuelve 0 si a es igual a b, 1 si a>b y -1 si a

  • void List_RemoveLastOcurrence(List*L,NodeList*element,cmpfn comparable){NodeList*iterator=NULL;NodeList*tmp=NULL;for(iterator=listGetHeader(L);iterator!=NULL;iterator=nodeListGetNext(iterator){

    if(comparable(element->cont,iterator->cont==0){tmp=iterator;//tmp almacenara la ultima ocurrencia de element

    }}if(tmp==NULL){//si tmp nunca entro al condicional definido dentro del ciclo for entonces

    quiere decir que element no se encuentra en la listaprintf(No se ha encontrado element en la lista);return;

    }else{// el paso final es remover element de la lista Literator=listGetPrevious(L,tmp);iterator->next=tmp->next;tmp->next=NULL;tmp=NULL;return;

    }}