El blog de Ronny, dedicado a la libertad de acceso al conocimiento.
Listas enlazadas Clase Lista,Nodo en c++ con 17 comentarios Una lista es una estructura de datos que nos permite agrupar elementos de una manera organizada. Las listas al igual que los algoritmos son importantsimas en la computacin y crticas en muchos programas informticos. Las listas estn compuestas por nodos, estos nodos tienen un dato o valor y un puntero a otro(s) nodo(s). Existen varios tipos de listas: Simplemente enlazada, doblemente enlazada, circular simplemente enlazada, circular doblemente enlazada. Vamos a revisar las listas enlazadas simples, por ser el punto de partida y fundamentales para poder entender las otras. Una lista enlazada tiene un conjunto de nodos, los cuales almacenan 2 tipos de informacin: El dato que contienen y un puntero al siguiente nodo en la lista. El ltimo nodo de la lista tiene como siguiente nodo el valor NULL. Entonces las listas enlazadas simples solo pueden ser recorridas en una direccin, apuntando al nodo siguiente, mas no a un nodo anterior. Aqu una ejemplo de un lista enlazada simple. 01 En cristiano: 02 55-> 60-> 31-> 5-> 4-> 51-> 9-> 27-> 68-> 62-> NULL 03 04 Internamente: 05 Nodo-> Dato: 55 Direcion: 0x3d2c00 Siguiente: 0x3d2c80 06 Nodo-> Dato: 60 Direcion: 0x3d2c80 Siguiente: 0x3d2c90 07 Nodo-> Dato: 31 Direcion: 0x3d2c90 Siguiente: 0x3d2ca0 08 Nodo-> Dato: 5 Direcion: 0x3d2ca0 Siguiente: 0x3d2cb0 09 Nodo-> Dato: 4 Direcion: 0x3d2cb0 Siguiente: 0x3d2cc0 10 Nodo-> Dato: 51 Direcion: 0x3d2cc0 Siguiente: 0x3d3ab8 11 Nodo-> Dato: 9 Direcion: 0x3d3ab8 Siguiente: 0x3d3ac8 12 Nodo-> Dato: 27 Direcion: 0x3d3ac8 Siguiente: 0x3d3ad8 13 Nodo-> Dato: 68 Direcion: 0x3d3ad8 Siguiente: 0x3d3ae8 14 Nodo-> Dato: 62 Direcion: 0x3d3ae8 Siguiente: 0 Obviamente, internamente no existen las palabras nodo, dato,direccin y siguiente, es solo una representacin. Como una lista es una estructura de datos dinmica, el tamao de la misma puede cambiar durante la ejecucin del programa. Como vimos en post anteriores, se puede generar memoria dinmicamente para un array, pero un array es una estructura esttica pues su tamao tiene un limite y as creramos array dinmicos hay que redimensionar el tamao si es necesario, lo cual ya implica un costo de volver a generar memoria dinmica. Entonces podemos ver una ventaja de la listas sobre los arrays: No tener que redimensionar la estructura y poder agregar elemento tras elemento indefinidamente. Cuando uno ya ha trabajado con arrays (vectores y matrices) y empieza a estudiar las listas, se da cuenta que una restriccin de las listas es el acceso a los elementos. En un vector podamos hacer algo como v[50] y nos estbamos refiriendo al ndice 50 del vector v. A esto se le conoce como acceso aleatorio. En el caso de las listas el acceso es secuencial, es decir, para acceder a un elemento del conjunto debemos de recorrer uno por uno los elementos hasta llegar al solicitado. Rpidamente se puede concluir que el tiempo de acceso a los elementos de un array es muchsimo ms rpido que en una lista. Esta es una gran desventaja de las listas, por lo que buscar elementos por ndice sera muy costoso. Esto no quiere decir que trabajar con arrays sea mejor que con listas. Las listas son muy flexibles y para muchos casos son imprescindibles. Bueno, aqu va la primera prctica que hice sobre listas enlazadas. Implementacin de una clase Lista, clase Nodo y los siguientes mtodos: Aadir un elemento al inicio. Aadir un elemento al final Aadir un elemento de manera ordenada Llenar la lista por teclado Llenar la lista aleatoriamente Imprimir la lista Buscar un elemento Eliminar un elemento por dato Eliminar un elemento por posicion o ndice Eliminar toda la lista Invertir una lista Ordernar una lista Cargar una lista desde archivo Guardar la lista en un archivo Concatenar una lista a otra Interseccin entre 2 listas Podrn ver la variable *temp en casi todos los mtodos , este es el puntero de tipo Nodo que me va a permitir moverme a travs de la lista y que inicialmente es igual a la cabeza (head). Mientras exista algo en la lista, voy avanzado el puntero para que apunte al siguiente. Esto se consigue en casi todos los casos con un while. While(temp) temp = temp->gte Otra operacin comn en los mtodos es preguntar si inicialmente la lista est vaca, es decir, si la cabeza no contiene algo o es igual a Null. if(!head) o if(head==NULL) Apliqu mis limitados conocimientos de templates para tener una lista genrica y as pueda funcionar con varios tipos de datos y de verdad funciona. Ah la definicin e implementacin de la clase, lista, clase nodo y el main para ver el funcionamiento. Cualquier crtica, sugerencia o comentarios son bienvenidos siempre. Nodo.h 01 #ifndef NODO_H 02 #define NODO_H 03 #include <iostream> 04 05 using namespace std; 06 template <class T> 07 class Nodo 08 { 09 public: 10 T dato; 11 Nodo *sgte; 12 Nodo(); 13 Nodo(T); 14 ~Nodo(); 15
284 //numeros que coinciden en 2 listas 285 template<typename T> 286 void Lista<T>::interseccion(Lista Lista2) 287 { 288 Nodo<T> *temp = head; 289 Nodo<T> *temp2 = Lista2.head;//cabeza de la segunda lista 290 Lista lista_interseccion;//creo otra lista 291
292 int num_nodos2 = Lista2.num_nodos;//nodos de la segunda lista 293 int num_inter=0;//numero de coincidencias 294
295 //creo 2 vectores dinamicos 296 T *v1 = new T[num_nodos]; 297 T *v2 = new T[num_nodos2]; 298 299 //lleno los vectores v1 y v2 con los datos de la lista original y segunda lista respectivamente 300 int i=0; 301 while(temp){ 302 v1[i] = temp->dato; 303 temp = temp->sgte; 304 i++; 305 } 306 307 int j=0; 308 while(temp2){ 309 v2[j] = temp2->dato; 310 temp2 = temp2->sgte; 311 j++; 312 } 313
314 //ordeno los vectores 315 insert_sort(v1,num_nodos); 316 insert_sort(v2,num_nodos2); 317 318 int v1_i= 0;//indice del 1er vector (v1) 319 int v2_i= 0;//indice del 2do vector (v2) 320
321 //mientras no haya terminado de recorrer ambas listas 322 while (v1_i < num_nodos && v2_i < num_nodos2) { 323 if(v1[v1_i] == v2[v2_i]){//cuando los datos de ambas sean iguales 324 lista_interseccion.add_end(v1[v1_i]);//utilizo mi metodo add_end para llenar la lista de intersecciones 325 v1_i++; 326 v2_i++; 327 num_inter++; 328 } else if(v1[v1_i] < v2[v2_i]){ 329 v1_i++; 330 } else{ 331 v2_i++; 332 } 333 } 334
335 //Solo si hay alguna interseccion imprimo la nueva lista creada 336 if(num_inter > 0) { 337 cout << "Existen " << num_inter << " intersecciones " << endl; 338 lista_interseccion.print(); 339 } else { 340 cout << "No hay interseccion en ambas listas" << endl; 341 } 342 } 343
44 cout << "Elimina un elemento por dato" << endl; 45 cin >>l1.ele; 46 l1.del_dato(l1.ele); 47 l1.print(); 48
49 cout << "Elimina un elemento por posicion" << endl; 50 cin >>pos; 51 l1.del_pos(pos); 52 l1.print(); 53
54 cout << "Cargar una lista desde archivo - Ingresa el nombre" << endl; 55 cin >> archivo;//debe estar en el mismo directorio que este programa 56 l2.load(archivo); 57 cout << "Lista B" << endl; 58 l2.print(); 59
60 cout << "Guardar la lista en un archivo - Ingresa el nombre" << endl; 61 cin >> archivo;//ingresa un nombre cualquiera *.* 62 l2.save(archivo); 63
64 cout << "Interseccion entre las listas A y B " << endl; 65 l1.interseccion(l2); 66
67 cout << "Listas A y B concatenadas " << endl; 68 l1.concat(l2); 69 l1.print(); 70
71 l1.del_all(); 72 l1.print(); 73 74 return 0; 75 } Un ejemplo de la salida del programa: 01 Ingresa la dimension de la lista 02 10 03 Lista A al inicio 04 55-> 60-> 31-> 5-> 4-> 51-> 9-> 27-> 68-> 62-> NULL 05
06 Agrega un elemento por la cabeza 07 18 08 18-> 55-> 60-> 31-> 5-> 4-> 51-> 9-> 27-> 68-> 62-> NULL 09
20 Busca un elemento 21 51 22 El dato se encuentra en la posicion: 8 (Para seres humanos) 23 24 Elimina un elemento por dato 25 60 26 4-> 5-> 9-> 18-> 27-> 31-> 45-> 51-> 55-> 62-> 68-> NULL 27
32 Cargar una lista desde archivo - Ingresa el nombre 33 prueba.txt // mi archivito prueba.txt tenia estos datos 34 Lista B 35 8-> 59-> 23-> 15-> 94-> 63-> 9-> 17-> 62-> 33-> NULL 36 37 Guardar la lista en un archivo - Ingresa el nombre 38 otralista.txt // abre tu archivo y mira el contenido 39 Interseccion entre las listas A y B 40 Existen 2 intersecciones 41 9-> 62-> NULL 42
43 Listas A y B concatenadas 44 4-> 5-> 9-> 18-> 27-> 31-> 45-> 51-> 55-> 62-> 8-> 59-> 23-> 15-> 94-> 63-> 9->17-> 62-> 33-> NULL 45
46 La lista esta vacia. Gracias por tu visita al blog. Puedes seguirme en Twitter haciendo click en el siguiente enlace