Professional Documents
Culture Documents
Lista (informtica)
En Ciencias de la Computacin, una lista enlazada es una de las estructuras de datos fundamentales, y puede ser usada para implementar otras estructuras de datos. Consiste en una secuencia de nodos, en los que se guardan campos de datos arbitrarios y una o dos referencias, enlaces o punteros al nodo anterior o posterior. El principal beneficio de las listas enlazadas respecto a los vectores convencionales es que el orden de los elementos enlazados puede ser diferente al orden de almacenamiento en la memoria o el disco, permitiendo que el orden de recorrido de la lista sea diferente al de almacenamiento. Una lista enlazada es un tipo de dato autorreferenciado porque contienen un puntero o enlace (en ingls link, del mismo significado) a otro dato del mismo tipo. Las listas enlazadas permiten inserciones y eliminacin de nodos en cualquier punto de la lista en tiempo constante (suponiendo que dicho punto est previamente identificado o localizado), pero no permiten un acceso aleatorio. Existen diferentes tipos de listas enlazadas: listas enlazadas simples, listas doblemente enlazadas, listas enlazadas circulares y listas enlazadas doblemente circulares. Las listas enlazadas pueden ser implementadas en muchos lenguajes. Lenguajes tales como Lisp y Scheme tiene estructuras de datos ya construidas, junto con operaciones para acceder a las listas enlazadas. Lenguajes imperativos u orientados a objetos tales como C o C++ y Java, respectivamente, disponen de referencias para crear listas enlazadas.
Historia
Las listas enlazadas fueron desarrolladas en 1955-56 por Cliff Shaw y Herbert Simon en RAND Corporation, como la principal estructura de datos para su Lenguaje de Procesamiento de la Informacin (IPL). IPL fue usado por los autores para desarrollar varios programas relacionados con la inteligencia artificial, incluida la Mquina de la Teora General, el Solucionador de Problemas Generales, y un programa informtico de ajedrez. Se public en IRE Transactions on Information Theory en 1956, y en distintas conferencias entre 1957-1959, incluida Proceedings of the Western Joint Computer en 1957 y 1958, y en Information Processing (Procendents de la primera conferencia internacional del procesamiento de la informacin de la Unesco) en 1959. El diagrama clsico actual, que consiste en bloques que representan nodos de la lista con flechas apuntando a los sucesivos nodos de la lista, apareci en Programming the Logic Theory Machine, de Newell y Shaw. Newell y Simon fueron reconocidos por el ACM Turing Award en 1975 por hacer contribuciones bsicas a la inteligencia artificial, a la psicologa del conocimiento humano y al procesamiento de las listas. El problema de los traductores del procesamiento natural del lenguaje condujo a Victor Yngve del Instituto Tecnolgico de Massachusetts (MIT) a usar listas enlazadas como estructura de datos en su COMIT, lenguaje de programacin para computadoras, que investig en el campo de la Lingstica computacional. Un informe de este lenguaje, titulado A programming language for mechanical translation apareci en Mechanical Translation en 1958. LISP, el principal procesador de listas, fue creado en 1958. Una de las mayores estructuras de datos de LISP es la lista enlazada. En torno a los 60, la utilidad de las listas enlazadas y los lenguajes que utilizaban estas estructuras como su principal representacin de datos estaba bien establecida. Bert Green, del Lincoln Laboratory del MIT, public un estudio titulado Computer languages for symbol manipulation en IRE Transaction on Human Factors in Electronics en marzo de 1961 que resuma las ventajas de las listas enlazadas. Un posterior artculo, A Comparison of list-processing computer languages de Bobrow y Raphael, apareca en Communications of the ACM en abril de 1964. Muchos sistemas operativos desarrollados por la empresa Technical Systems Consultants (originalmente de West Lafayette Indiana y despus de Raleigh, Carolina del Norte) usaron listas enlazadas simples como estructuras de
Lista (informtica) ficheros. Un directorio de entrada apuntaba al primer sector de un fichero y daba como resultado porciones de la localizacin del fichero mediante punteros. Los sistemas que utilizaban esta tcnica incluan Flex (para el Motorola 6800 CPU), mini-Flex (la misma CPU) y Flex9 (para el Motorola 6809 CPU). Una variante desarrollada por TSC se comercializ a Smoke Signal Broadcasting en California, usando listas doblemente enlazadas del mismo modo. El sistema operativo TSS, desarrollado por IBM para las mquinas System 360/370, usaba una lista doblemente enlazada para su catlogo de ficheros de sistema. La estructura de directorios era similar a Unix, donde un directorio poda contener ficheros u otros directorios que se podan extender a cualquier profundidad. Una utilidad fue creada para arreglar problemas del sistema despus de un fallo desde las porciones modificadas del catlogo de ficheros que estaban a veces en memoria cuando ocurra el fallo. Los problemas eran detectados por comparacin de los enlaces posterior y anterior por consistencia. Si el siguiente de ellos era corrupto y el anterior enlace del nodo infectado era encontrado, el enlace posterior era asignado al nodo marcado con el enlace anterior.
Listas enlazadas simples circulares Cada nodo tiene un enlace, similar al de las listas enlazadas simples, excepto que el siguiente nodo del ltimo apunta al primero. Como en una lista enlazada simple, los nuevos nodos pueden ser solo eficientemente insertados despus de uno que ya tengamos referenciado. Por esta razn, es usual quedarse con una referencia solamente al ltimo elemento en una lista enlazada circular simple, esto nos permite rpidas inserciones al principio, y tambin permite accesos al primer nodo desde el puntero del ltimo nodo.
Lista (informtica) Listas enlazadas doblemente circulares En una lista enlazada doblemente circular, cada nodo tiene dos enlaces, similares a los de la lista doblemente enlazada, excepto que el enlace anterior del primer nodo apunta al ltimo y el enlace siguiente del ltimo nodo, apunta al primero. Como en una lista doblemente enlazada, las inserciones y eliminaciones pueden ser hechas desde cualquier punto con acceso a algn nodo cercano. Aunque estructuralmente una lista circular doblemente enlazada no tiene ni principio ni fin, un puntero de acceso externo puede establecer el nodo apuntado que est en la cabeza o al nodo cola, y as mantener el orden tan bien como en una lista doblemente enlazada.
Nodos centinelas
A veces las listas enlazadas tienen un nodo centinela (tambin llamado falso nodo o nodo ficticio) al principio o al final de la lista, el cual no es usado para guardar datos. Su propsito es simplificar o agilizar algunas operaciones, asegurando que cualquier nodo tiene otro anterior o posterior, y que toda la lista (incluso alguna que no contenga datos) siempre tenga un primer y ltimo nodo.
Ventajas
Como muchas opciones en programacin y desarrollo, no existe un nico mtodo correcto para resolver un problema. Una estructura de lista enlazada puede trabajar bien en un caso pero causar problemas en otros. He aqu una lista con algunas de las ventajas ms comunes que implican las estructuras de tipo lista. En general, teniendo una coleccin dinmica donde los elementos estn siendo aadidos y eliminados frecuentemente e importa la localizacin de los nuevos elementos introducidos se incrementa el beneficio de las listas enlazadas.
Lista (informtica)
Vector Lista Enlazada Indexado Insercin / Eliminacin al final O(1) O(1) O(n) O(1) or O(n) O(1) Simples s Mala [1]
Las listas enlazadas poseen muchas ventajas sobre los vectores. Los elementos se pueden insertar en una lista indefinidamente mientras que un vector tarde o temprano se llenar o necesitar ser redimensionado, una costosa operacin que incluso puede no ser posible si la memoria se encuentra fragmentada. En algunos casos se pueden lograr ahorros de memoria almacenando la misma cola de elementos entre dos o ms listas es decir, la lista acaba en la misma secuencia de elementos. De este modo, uno puede aadir nuevos elementos al frente de la lista manteniendo una referencia tanto al nuevo como a los viejos elementos - un ejemplo simple de una estructura de datos persistente. Por otra parte, los vectores permiten acceso aleatorio mientras que las listas enlazadas slo permiten acceso secuencial a los elementos. Las listas enlazadas simples, de hecho, solo pueden ser recorridas en una direccin. Esto hace que las listas sean inadecuadas para aquellos casos en los que es til buscar un elementos por su ndice rpidamente, como el heapsort. El acceso secuencial en los vectores tambin es ms rpido que en las listas enlazadas. Otra desventaja de las listas enlazadas es el almacenamiento extra necesario para las referencias, que a menudos las hacen poco prcticas para listas de pequeos datos como caracteres o valores booleanos. Tambin puede resultar lento y abusivo el asignar memoria para cada nuevo elemento. Existe una variedad de listas enlazadas que contemplan los problemas anteriores para resolver los mismos. Un buen ejemplo que muestra los pros y contras del uso de vectores sobre listas enlazadas es la implementacin de un programa que resuelva el problema de Josephus. Este problema consiste en un grupo de personas dispuestas en forma de crculo. Se empieza a partir de una persona predeterminadas y se cuenta n veces, la persona n-sima se saca del crculo y se vuelve a cerrar el grupo. Este proceso se repite hasta que queda una sola persona, que es la que gana. Este ejemplo muestra las fuerzas y debilidades de las listas enlazadas frente a los vectores, ya que viendo a la gente como nodos conectados entre s en una lista circular se observa como es ms fcil suprimir estos nodos. Sin embargo, se ve como la lista perder utilidad cuando haya que encontrar a la siguiente persona a borrar. Por otro lado, en un vector el suprimir los nodos ser costoso ya que no se puede quitar un elemento sin reorganizar el resto. Pero en la bsqueda de la n-sima persona tan slo basta con indicar el ndice n para acceder a l resultando mucho ms eficiente.
Lista (informtica)
Lista (informtica)
Lenguajes soportados
Muchos lenguajes de programacin tales como Lisp y Scheme tienen listas enlazadas simples ya construidas. En muchos lenguajes de programacin, estas listas estn construidas por nodos, cada uno llamado cons o celda cons. Las celdas cons tienen dos campos: el car, una referencia del dato al nodo, y el cdr, una referencia al siguiente nodo. Aunque las celdas cons pueden ser usadas para construir otras estructuras de datos, este es su principal objetivo. En lenguajes que soportan tipos abstractos de datos o plantillas, las listas enlazadas ADTs o plantillas estn disponibles para construir listas enlazadas. En otros lenguajes, las listas enlazadas son tpicamente construidas usando referencias junto con el tipo de dato record. En la seccin de implementaciones hay un ejemplo completo en C y en Maude
Lista (informtica) almacenadas en dos listas enlazadas usando la misma estructura de datos (nodo), y este lenguaje no tiene tipos paramtricos. Si conocemos el nmero de familias a las que un miembro puede pertenecer en tiempo de compilacin, el almacenamiento interno trabaja mejor. Si, sin embargo, un miembro necesita ser incluido en un nmero arbitrario de familias, sabiendo el nmero especfico de familias solo en tiempo de ejecucin, el almacenamiento externo ser necesario.
Agilizacin de la bsqueda
Buscando un elemento especfico en una lista enlazada, incluso si esta es ordenada, normalmente requieren tiempo O (n) (bsqueda lineal). Esta es una de las principales desventajas de listas enlazadas respecto a otras estructuras. Adems algunas de las variantes expuestas en la seccin anterior, hay numerosas vas simples para mejorar el tiempo de bsqueda. En una lista desordenada, una forma simple para decrementar el tiempo de bsqueda medio es el mover al frente de forma heurstica, que simplemente mueve un elemento al principio de la lista una vez que es encontrado. Esta idea, til para crear cachs simples, asegura que el tem usado ms recientemente es tambin el ms rpido en ser encontrado otra vez. Otro enfoque comn es indizar una lista enlazada usando una estructura de datos externa ms eficiente. Por ejemplo, podemos construir un rbol rojo-negro o una tabla hash cuyos elementos estn referenciados por los nodos de las listas enlazadas. Pueden ser construidos mltiples ndices en una lista simple. La desventaja es que estos ndices puede necesitar ser actualizados cada vez que uno nodo es aadido o eliminado (o al menos, antes que el ndice sea utilizado otra vez).
Lista (informtica)
Implementaciones
Aqu se expone el cdigo necesario para complementar el artculo a fin de poder realizar una lectura gil sobre el artculo y a su vez quien necesite el cdigo pueda fcilmente encontrar el mismo si est contenido.
El recorrido en una lista enlazada es simple, empezamos por el primer nodo y pasamos al siguiente hasta que la lista llegue al final. node := list.PrimerNodo while node not null { node := node.next } El siguiente cdigo inserta un elemento a continuacin de otro en una lista simple. El diagrama muestra como funciona.
function insertAfter(Node node, Node newNode) { newNode.next := node.next node.next := newNode } Insertar al principio de una lista requiere una funcin por separado. Se necesita actualizar PrimerNodo.
Lista (informtica) function insertBeginning(List list, Node newNode) { newNode.next := list.firstNode list.firstNode := newNode } De forma similar, tambin tenemos funciones para borrar un nodo dado para borrar un nodo del principio de la lista. Ver diagrama.
function removeAfter(Node node) { obsoleteNode := node.next node.next := node.next.next destroy obsoleteNode } function removeBeginning(List list) { obsoleteNode := list.firstNode list.firstNode := list.firstNode.next destroy obsoleteNode } Advertimos que BorrarPrincipio pone PrimerNodo a nulo cuando se borra el ltimo elemento de la lista. Adjuntar una lista enlazada a otra puede resultar ineficiente a menos que se guarde una referencia a la cola de la lista, porque si no tendramos que recorrer la lista en orden hasta llegar a la cola y luego aadir la segunda lista. Listas doblemente enlazadas Con estas listas es necesario actualizar muchos ms punteros pero tambin se necesita menos informacin porque podemos usar un puntero para recorrer hacia atrs y consultar elementos. Se crean nuevas operaciones y elimina algunos casos especiales. Aadimos el campo anterior a nuestros nodos, apuntando al elemento anterior, y UltimoNodo a nuestra estructura, el cual siempre apunta al ltimo elemento de la lista. PrimerNodo y UltimoNodo siempre estn a nulo en la lista vaca. record Node { data // El dato almacenado en el nodo next // Una referencia al nodo siguiente, nulo para el ltimo nodo prev // Una referencia al nodo anterior, nulo para el primer nodo }
record List { Node firstNode Node lastNode } // apunta al primer nodo de la lista; nulo para la lista vaca // apunta al ltimo nodo de la lista; nulo para la lista vaca
Lista (informtica) Formas de recorrer la lista: Hacia Delante node := list.firstNode while node null <do something with node.data> node := node.next Hacia Atrs node := list.lastNode while node null <do something with node.data> node := node.prev Estas funciones simtricas aaden un nodo despus o antes de uno dado: function insertAfter(List list, Node node, Node newNode) newNode.prev := node newNode.next := node.next if node.next = null node.next := newNode list.lastNode := newNode else node.next.prev := newNode node.next := newNode function insertBefore(List list, Node node, Node newNode) newNode.prev := node.prev newNode.next := node if node.prev is null node.prev := newNode list.firstNode := newNode else node.prev.next := newNode node.prev := newNode Tambin necesitamos una funcin para insertar un nodo al comienzo de una lista posiblemente vaca. function insertBeginning(List list, Node newNode) if list.firstNode = null list.firstNode := newNode list.lastNode := newNode newNode.prev := null newNode.next := null else insertBefore (list, list.firstNode, newNode) Una funcin simtrica que inserta al final: function insertEnd(List list, Node newNode) if list.lastNode = null
10
Lista (informtica) insertBeginning (list, newNode) else insertAfter (list, list.lastNode, newNode) Borrar un nodo es fcil, solo requiere usar con cuidado firstNode y lastNode. function remove(List list, Node node) if node.prev = null list.firstNode := node.next else node.prev.next := node.next if node.next = null list.lastNode := node.prev else node.next.prev := node.prev destroy node Una consecuencia especial de este procedimiento es que borrando el ltimo elemento de una lista se ponen PrimerNodo y UltimoNodo a nulo, habiendo entonces un problema en una lista que tenga un nico elemento. Listas enlazadas circulares Estas pueden ser simples o doblemente enlazadas. En una lista circular todos los nodos estn enlazados como un crculo, sin usar nulo. Para listas con frente y final (como una cola), se guarda una referencia al ltimo nodo de la lista. El siguiente nodo despus del ltimo sera el primero de la lista. Los elementos se pueden aadir por el final y borrarse por el principio en todo momento. Ambos tipos de listas circulares tienen la ventaja de poderse recorrer completamente empezando desde cualquier nodo. Esto nos permite normalmente evitar el uso de PrimerNodo y UltimoNodo, aunque si la lista estuviera vaca necesitaramos un caso especial, como una variables UltimoNodo que apunte a algn nodo en la lista o nulo si est vaca. Las operaciones para estas listas simplifican el insertar y borrar nodos en una lista vaca pero introducen casos especiales en la lista vaca. Listas enlazadas doblemente circulares Asumiendo que someNodo es algn nodo en una lista no vaca, esta lista presenta el comienzo de una lista con someNode. Hacia Delante node := someNode do do something with node.value node := node.next while node != someNode Hacia Atrs node := someNode do do something with node.value node := node.prev while node := someNode Esta funcin inserta un nodo en una lista enlazada doblemente circular despus de un elemento dado:
11
Lista (informtica) function insertAfter(Node node, Node newNode) newNode.next := node.next newNode.prev := node node.next.prev := newNode node.next := newNode Para hacer "insertBefore", podemos simplificar "insertAfter (node.prev, newNode)". Insertar un elemento en una lista que puede estar vaca requiere una funcin especial. function insertEnd(List list, Node node) if list.lastNode = null node.prev := node node.next := node else insertAfter (list.lastNode, node) list.lastNode := node Para insertar al principio simplificamos "insertAfter (list.lastNode, node)". function remove(List list, Node node) if node.next = node list.lastNode := null else node.next.prev := node.prev node.prev.next := node.next if node = list.lastNode list.lastNode := node.prev; destroy node Como una lista doblemente enlazada, "removeAfter" y "removeBefore" puede ser implementada con "remove (list, node.prev)" y "remove (list, node.next)".
12
Lista (informtica)
13
typedef struct ns { int data; struct ns *next; } node; node *list_add(node **p, int i) { /* algunos compiladores no requieren un casting del valor del retorno para malloc */ node *n = (node *)malloc(sizeof(node)); if (n == NULL) return NULL; n->next = *p; *p = n; n->data = i; return n; } void list_remove(node **p) { /* borrar cabeza*/ if (*p != NULL) { node *n = *p; *p = (*p)->next; free(n); } } node **list_search(node **n, int i) { while (*n != NULL) { if ((*n)->data == i) { return n; } n = &(*n)->next; } return NULL; } void list_print(node *n) { if (n == NULL) { printf("lista esta vaca\n"); } while (n != NULL) { printf("print %p %p %d\n", n, n->next, n->data);
Lista (informtica) n = n->next; } } int main(void) { node *n = NULL; list_add(&n, 0); /* lista: 0 */ list_add(&n, 1); /* lista: 1 0 */ list_add(&n, 2); /* lista: 2 1 0 */ list_add(&n, 3); /* lista: 3 2 1 0 */ list_add(&n, 4); /* lista: 4 3 2 1 0 */ list_print(n); list_remove(&n); /* borrar primero(4) */ list_remove(&n->next); /* borrar nuevo segundo (2) */ list_remove(list_search(&n, 1)); /* eliminar la celda que contiene el 1 (primera) */ list_remove(&n->next); /* eliminar segundo nodo del final(0)*/ list_remove(&n); /* eliminar ultimo nodo (3) */ list_print(n); return 0; }
14
struct camera_t { int idcam; string serial; int idroom; camera_t *next; };
//Insertar al principio de una lista requiere una funcin por separado. Se necesita actualizar PrimerNodo. void list_add(camera_t **node_cam) { camera_t *newnode = new (nothrow) camera_t; if(newnode==NULL){ cout << "Error. No possible allocate memory to new node."; }
Lista (informtica)
else{ newnode->next = *node_cam; *node_cam = newnode; cout << "Hola"; } }
15
//El recorrido en una lista enlazada es simple, empezamos por el primer nodo y pasamos al siguiente hasta // que la lista llegue al final. void list_print(camera_t *node_cam) { if (node_cam == NULL){ cout << "Lista vacia"; } else{ while (node_cam!=NULL) { cout << "idcam: " << node_cam->idcam << "\nName: " << node_cam->name << "\nModel: " << node_cam->model; cout << "\nSerial: " << node_cam->serial << "\nIdRoom: " << node_cam->idroom << "\nNameRoom: " << node_cam->room; cout << "\n\n"; node_cam = node_cam->next; } } }
list_add(&node_cam);
cout << "Indentificador de camara: 23"; node_cam->idcam = N_globalCamera; node_cam->name = "PanSonyc"; cout << "Precione una tecla para regresar al menu principal."; getline(cin,mystr);
list_print(node_cam); }
Lista (informtica)
16
*** selectores op primero : ListaGenNV{X} -> X$Elt . op esVacia? : ListaGen{X} -> Bool . op longitud : ListaGen{X} -> Nat . *** variables vars L L1 L2 : ListaGen{X} . vars E E1 E2 : X$Elt . *** ecuaciones eq esVacia?(crear) = true . eq esVacia?(cons(E, L)) = false .
eq primero(cons(E, L)) = E .
Lista (informtica)
eq resto(cons(E, L)) = L .
17
eq longitud(crear) = 0 . eq longitud(cons(E, L)) = 1 + longitud(L) . eq cons(E1, L1) :: cons(E2, L2) = cons(E1, L1 :: cons(E2, L2)) .
endfm
Usando almacenamiento externo, nosotros podramos crear las siguientes estructuras: record node { // estructura genrica de enlace node next pointer data // puntero genrico del dato al nodo
Lista (informtica) } record member { // estructura de una familia string firstName integer age } record family { // estructura de una familia string lastName string address node members // cabeza de la lista de miembros de esta familia } Para mostrar una lista completa de familias y sus miembros usando almacenamiento externo, podramos escribir: famNode := Families // comienzo de la cabeza de una lista de familias while famNode null { // bucle de lista de familias aFamily = (family) famNode.data // extraer familia del nodo print information about family memNode := aFamily.members // coger lista de miembros de familia while memNode null { bucle de lista de miembros aMember := (member) memNode.data // extraer miembro del nodo print information about member memNode := memNode.next } famNode := famNode.next }
18
Referencias
[1] If maintaining a link to the tail of the list, time is O(1); if the entire list must be searched to locate the tail link, O(n)
National Institute of Standards and Technology (August 16, 2004). Definition of a linked list (http://nist.gov/ dads/HTML/linkedList.html). Retrieved December 14, 2004. Antonakos, James L. and Mansfield, Kenneth C., Jr. Practical Data Structures Using C/C++ (1999). Prentice-Hall. ISBN 0-13-280843-9, pp. 165190 Collins, William J. Data Structures and the Java Collections Framework (2002,2005) New York, NY: McGraw Hill. ISBN 0-07-282379-8, pp. 239303 Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford Introductions to Algorithms (2003). MIT Press. ISBN 0-262-03293-7, pp. 205213, 501505 Green, Bert F. Jr. (1961). Computer Languages for Symbol Manipulation. IRE Transactions on Human Factors in Electronics. 2 pp. 3-8. McCarthy, John (1960). Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I. Communications of the ACM. (http://www-formal.stanford.edu/jmc/recursive.html) HTML (http:// www-formal.stanford.edu/jmc/recursive/recursive.html) DVI (http://www-formal.stanford.edu/jmc/ recursive.dvi) PDF (http://www-formal.stanford.edu/jmc/recursive.pdf) PostScript (http://www-formal. stanford.edu/jmc/recursive.ps) Donald Knuth. Fundamental Algorithms, Third Edition. Addison-Wesley, 1997. ISBN 0-201-89683-4. Sections 2.2.32.2.5, pp.254298. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Section 10.2: Linked lists,
Lista (informtica) pp.204209. Newell, Allen and Shaw, F. C. (1957). Programming the Logic Theory Machine. Proceedings of the Western Joint Computer Conference. pp. 230-240. Parlante, Nick (2001). Linked list basics. Stanford University. PDF (http://cslibrary.stanford.edu/103/ LinkedListBasics.pdf) Sedgewick, Robert Algorithms in C (1998). Addison Wesley. ISBN 0-201-31452-5, pp. 90109 Shaffer, Clifford A. A Practical Introduction to Data Structures and Algorithm Analysis (1998). NJ: Prentice Hall. ISBN 0-13-660911-2, pp. 77102 Wilkes, Maurice Vincent (1964). An Experiment with a Self-compiling Compiler for a Simple List-Processing Language. Annual Review in Automatic Programming 4, 1. Published by Pergamon Press. Wilkes, Maurice Vincent (1964). Lists and Why They are Useful. Proceeds of the ACM National Conference, Philadelphia 1964 (ACM Publication P-64 page F1-1); Also Computer Journal 7, 278 (1965). Kulesh Shanmugasundaram (April 4, 2005). Linux Kernel Linked List Explained (http://isis.poly.edu/kulesh/ stuff/src/klist/).
19
20
Licencia
Creative Commons Attribution-Share Alike 3.0 //creativecommons.org/licenses/by-sa/3.0/