![Singly-linked-list](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg)
In
computer science
Computer science is the study of computation, automation, and information. Computer science spans theoretical disciplines (such as algorithms, theory of computation, information theory, and automation) to Applied science, practical discipli ...
, a linked list is a linear collection of data elements whose order is not given by their physical placement in memory. Instead, each element
points to the next. It is a
data structure
In computer science, a data structure is a data organization, management, and storage format that is usually chosen for efficient access to data. More precisely, a data structure is a collection of data values, the relationships among them, a ...
consisting of a collection of
node
In general, a node is a localized swelling (a "knot") or a point of intersection (a vertex).
Node may refer to:
In mathematics
*Vertex (graph theory), a vertex in a mathematical graph
*Vertex (geometry), a point where two or more curves, lines, ...
s which together represent a
sequence
In mathematics, a sequence is an enumerated collection of objects in which repetitions are allowed and order matters. Like a set, it contains members (also called ''elements'', or ''terms''). The number of elements (possibly infinite) is calle ...
. In its most basic form, each node contains:
data
In the pursuit of knowledge, data (; ) is a collection of discrete values that convey information, describing quantity, quality, fact, statistics, other basic units of meaning, or simply sequences of symbols that may be further interpreted ...
, and a
reference
Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a ''name'' ...
(in other words, a ''link'') to the next node in the sequence. This structure allows for efficient insertion or removal of elements from any position in the sequence during iteration. More complex variants add additional links, allowing more efficient insertion or removal of nodes at arbitrary positions. A drawback of linked lists is that access time is linear (and difficult to
pipeline
Pipeline may refer to:
Electronics, computers and computing
* Pipeline (computing), a chain of data-processing stages or a CPU optimization found on
** Instruction pipelining, a technique for implementing instruction-level parallelism within a s ...
). Faster access, such as random access, is not feasible.
Arrays
An array is a systematic arrangement of similar objects, usually in rows and columns.
Things called an array include:
{{TOC right
Music
* In twelve-tone and serial composition, the presentation of simultaneous twelve-tone sets such that the ...
have better
cache locality
In computer science, locality of reference, also known as the principle of locality, is the tendency of a processor to access the same set of memory locations repetitively over a short period of time. There are two basic types of reference localit ...
compared to linked lists.
Linked lists are among the simplest and most common data structures. They can be used to implement several other common
abstract data type
In computer science, an abstract data type (ADT) is a mathematical model for data types. An abstract data type is defined by its behavior (semantics) from the point of view of a ''user'', of the data, specifically in terms of possible values, pos ...
s, including
lists
A ''list'' is any set of items in a row. List or lists may also refer to:
People
* List (surname)
Organizations
* List College, an undergraduate division of the Jewish Theological Seminary of America
* SC Germania List, German rugby unio ...
,
stacks,
queues,
associative array
In computer science, an associative array, map, symbol table, or dictionary is an abstract data type that stores a collection of (key, value) pairs, such that each possible key appears at most once in the collection. In mathematical terms an ...
s, and
S-expression
In computer programming, an S-expression (or symbolic expression, abbreviated as sexpr or sexp) is an expression in a like-named notation for nested list (tree-structured) data. S-expressions were invented for and popularized by the programming la ...
s, though it is not uncommon to implement those data structures directly without using a linked list as the basis.
The principal benefit of a linked list over a conventional
array
An array is a systematic arrangement of similar objects, usually in rows and columns.
Things called an array include:
{{TOC right
Music
* In twelve-tone and serial composition, the presentation of simultaneous twelve-tone sets such that the ...
is that the list elements can be easily inserted or removed without reallocation or reorganization of the entire structure because the data items need not be stored
contiguously in memory or on disk, while restructuring an array at
run-time is a much more expensive operation. Linked lists allow insertion and removal of nodes at any point in the list, and allow doing so with a constant number of operations by keeping the link previous to the link being added or removed in memory during list traversal.
On the other hand, since simple linked lists by themselves do not allow
random access
Random access (more precisely and more generally called direct access) is the ability to access an arbitrary element of a sequence in equal time or any datum from a population of addressable elements roughly as easily and efficiently as any othe ...
to the data or any form of efficient indexing, many basic operations—such as obtaining the last node of the list, finding a node that contains a given datum, or locating the place where a new node should be inserted—may require iterating through most or all of the list elements.
History
Linked lists were developed in 1955–1956, by
Allen Newell
Allen Newell (March 19, 1927 – July 19, 1992) was a researcher in computer science and cognitive psychology at the RAND Corporation and at Carnegie Mellon University’s School of Computer Science, Tepper School of Business, and Department ...
,
Cliff Shaw
John Clifford Shaw (February 23, 1922 – February 9, 1991) was a systems programmer at the RAND Corporation. He is a coauthor of the first artificial intelligence program, the Logic Theorist, and was one of the developers of General Problem Solve ...
and
Herbert A. Simon
Herbert Alexander Simon (June 15, 1916 – February 9, 2001) was an American political scientist, with a Ph.D. in political science, whose work also influenced the fields of computer science, economics, and cognitive psychology. His primary ...
at
RAND Corporation
The RAND Corporation (from the phrase "research and development") is an American nonprofit global policy think tank created in 1948 by Douglas Aircraft Company to offer research and analysis to the United States Armed Forces. It is financed ...
as the primary
data structure
In computer science, a data structure is a data organization, management, and storage format that is usually chosen for efficient access to data. More precisely, a data structure is a collection of data values, the relationships among them, a ...
for their
Information Processing Language
Information Processing Language (IPL) is a programming language created by Allen Newell, Cliff Shaw, and Herbert A. Simon at RAND Corporation and the Carnegie Institute of Technology about 1956. Newell had the job of language specifier-applicatio ...
. IPL was used by the authors to develop several early
artificial intelligence
Artificial intelligence (AI) is intelligence—perceiving, synthesizing, and inferring information—demonstrated by machines, as opposed to intelligence displayed by animals and humans. Example tasks in which this is done include speech re ...
programs, including the Logic Theory Machine, the
General Problem Solver General Problem Solver (GPS) is a computer program created in 1959 by Herbert A. Simon, J. C. Shaw, and Allen Newell (RAND Corporation) intended to work as a universal problem solver machine. In contrast to the former Logic Theorist project, the GP ...
, and a computer chess program. Reports on their work appeared in IRE Transactions on Information Theory in 1956, and several conference proceedings from 1957 to 1959, including Proceedings of the Western Joint Computer Conference in 1957 and 1958, and Information Processing (Proceedings of the first
UNESCO
The United Nations Educational, Scientific and Cultural Organization is a specialized agency of the United Nations (UN) aimed at promoting world peace and security through international cooperation in education, arts, sciences and culture. It ...
International Conference on Information Processing) in 1959. The now-classic diagram consisting of blocks representing list nodes with arrows pointing to successive list nodes appears in "Programming the Logic Theory Machine" by Newell and Shaw in Proc. WJCC, February 1957. Newell and Simon were recognized with the ACM
Turing Award
The ACM A. M. Turing Award is an annual prize given by the Association for Computing Machinery (ACM) for contributions of lasting and major technical importance to computer science. It is generally recognized as the highest distinction in compu ...
in 1975 for having "made basic contributions to artificial intelligence, the psychology of human cognition, and list processing".
The problem of
machine translation
Machine translation, sometimes referred to by the abbreviation MT (not to be confused with computer-aided translation, machine-aided human translation or interactive translation), is a sub-field of computational linguistics that investigates t ...
for
natural language
In neuropsychology, linguistics, and philosophy of language, a natural language or ordinary language is any language that has evolved naturally in humans through use and repetition without conscious planning or premeditation. Natural languages ...
processing led
Victor Yngve
Victor H. Yngve (July 5, 1920 – January 15, 2012W. John HutchinVictor Yngve obituary aclweb.org; accessed August 15, 2017.) was professor of linguistics at the University of Chicago and the Massachusetts Institute of Technology (1953-1965). H ...
at
Massachusetts Institute of Technology
The Massachusetts Institute of Technology (MIT) is a private land-grant research university in Cambridge, Massachusetts. Established in 1861, MIT has played a key role in the development of modern technology and science, and is one of the ...
(MIT) to use linked lists as data structures in his COMIT programming language for computer research in the field of
linguistics
Linguistics is the scientific study of human language. It is called a scientific study because it entails a comprehensive, systematic, objective, and precise analysis of all aspects of language, particularly its nature and structure. Linguis ...
. A report on this language entitled "A programming language for mechanical translation" appeared in Mechanical Translation in 1958.
Another early appearance of linked lists was by
Hans Peter Luhn
Hans Peter Luhn (July 1, 1896 – August 19, 1964) was a German researcher in the field of computer science and Library & Information Science for IBM, and creator of the Luhn algorithm, KWIC (Key Words In Context) indexing, and Selective ...
who wrote an internal
IBM memorandum in January 1953 that suggested the use of linked lists in chained hash tables.
[
]
LISP
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lisping ...
, standing for list processor, was created by
John McCarthy in 1958 while he was at MIT and in 1960 he published its design in a paper in the
Communications of the ACM
''Communications of the ACM'' is the monthly journal of the Association for Computing Machinery (ACM). It was established in 1958, with Saul Rosen as its first managing editor. It is sent to all ACM members.
Articles are intended for readers with ...
, entitled "Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I". One of LISP's major data structures is the linked list.
By the early 1960s, the utility of both linked lists and languages which use these structures as their primary data representation was well established. Bert Green of the
MIT Lincoln Laboratory
The MIT Lincoln Laboratory, located in Lexington, Massachusetts, is a United States Department of Defense federally funded research and development center chartered to apply advanced technology to problems of national security. Research and dev ...
published a review article entitled "Computer languages for symbol manipulation" in IRE Transactions on Human Factors in Electronics in March 1961 which summarized the advantages of the linked list approach. A later review article, "A Comparison of list-processing computer languages" by Bobrow and Raphael, appeared in Communications of the ACM in April 1964.
Several operating systems developed by
Technical Systems Consultants
Technical Systems Consultants (TSC) was a United States software company.
Headquartered first in West Lafayette, Indiana (it was started by Don Kinzer and Dave Shirk, EE graduate students at Purdue University) and later (1980) moved to Chapel Hill ...
(originally of West Lafayette Indiana, and later of Chapel Hill, North Carolina) used singly linked lists as file structures. A directory entry pointed to the first sector of a file, and succeeding portions of the file were located by traversing pointers. Systems using this technique included Flex (for the
Motorola 6800
The 6800 ("''sixty-eight hundred''") is an 8-bit computing, 8-bit microprocessor designed and first manufactured by Motorola in 1974. The MC6800 microprocessor was part of the Motorola 6800 family, M6800 Microcomputer System (latter dubbed ''68xx' ...
CPU), mini-Flex (same CPU), and Flex9 (for the Motorola 6809 CPU). A variant developed by TSC for and marketed by
Smoke Signal Broadcasting
Smoke is a suspension of airborne particulates and gases emitted when a material undergoes combustion or pyrolysis, together with the quantity of air that is entrained or otherwise mixed into the mass. It is commonly an unwanted by-product ...
in California, used doubly linked lists in the same manner.
The TSS/360 operating system, developed by IBM for the System 360/370 machines, used a double linked list for their file system catalog. The directory structure was similar to Unix, where a directory could contain files and other directories and extend to any depth.
Basic concepts and nomenclature
Each record of a linked list is often called an 'element' or '
node
In general, a node is a localized swelling (a "knot") or a point of intersection (a vertex).
Node may refer to:
In mathematics
*Vertex (graph theory), a vertex in a mathematical graph
*Vertex (geometry), a point where two or more curves, lines, ...
'.
The field of each node that contains the address of the next node is usually called the 'next link' or 'next pointer'. The remaining fields are known as the 'data', 'information', 'value', 'cargo', or 'payload' fields.
The 'head' of a list is its first node. The 'tail' of a list may refer either to the rest of the list after the head, or to the last node in the list. In
Lisp
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lisping ...
and some derived languages, the next node may be called the '
cdr' (pronounced ''could-er'') of the list, while the payload of the head node may be called the 'car'.
Singly linked list
Singly linked lists contain nodes which have a 'value' field as well as 'next' field, which points to the next node in line of nodes. Operations that can be performed on singly linked lists include insertion, deletion and traversal.
The following code demonstrates how to add a new node with the "value" to the end of a singly linked list:
node addNode(node head, int value)
Doubly linked list
In a 'doubly linked list', each node contains, besides the next-node link, a second link field pointing to the 'previous' node in the sequence. The two links may be called 'forward('s') and 'backwards', or 'next' and 'prev'('previous').
A technique known as
XOR-linking allows a doubly linked list to be implemented using a single link field in each node. However, this technique requires the ability to do bit operations on addresses, and therefore may not be available in some high-level languages.
Many modern operating systems use doubly linked lists to maintain references to active processes, threads, and other dynamic objects.
A common strategy for
rootkits
A rootkit is a collection of computer software, typically malicious, designed to enable access to a computer or an area of its software that is not otherwise allowed (for example, to an unauthorized user) and often masks its existence or the exis ...
to evade detection is to unlink themselves from these lists.
Multiply linked list
In a 'multiply linked list', each node contains two or more link fields, each field being used to connect the same set of data records in a different order of same set (e.g., by name, by department, by date of birth, etc.). While doubly linked lists can be seen as special cases of multiply linked list, the fact that the two and more orders are opposite to each other leads to simpler and more efficient algorithms, so they are usually treated as a separate case.
Circular linked list
In the last node of a list, the link field often contains a
null
Null may refer to:
Science, technology, and mathematics Computing
* Null (SQL) (or NULL), a special marker and keyword in SQL indicating that something has no value
* Null character, the zero-valued ASCII character, also designated by , often use ...
reference, a special value is used to indicate the lack of further nodes. A less common convention is to make it point to the first node of the list; in that case, the list is said to be 'circular' or 'circularly linked'; otherwise, it is said to be 'open' or 'linear'. It is a
list
A ''list'' is any set of items in a row. List or lists may also refer to:
People
* List (surname)
Organizations
* List College, an undergraduate division of the Jewish Theological Seminary of America
* SC Germania List, German rugby union ...
where the last pointer points to the first node.
In the case of a circular doubly linked list, the first node also points to the last node of the list.
Sentinel nodes
In some implementations an extra 'sentinel' or 'dummy' node may be added before the first data record or after the last one. This convention simplifies and accelerates some list-handling algorithms, by ensuring that all links can be safely dereferenced and that every list (even one that contains no data elements) always has a "first" and "last" node.
Empty lists
An empty list is a list that contains no data records. This is usually the same as saying that it has zero nodes. If sentinel nodes are being used, the list is usually said to be empty when it has only sentinel nodes.
Hash linking
The link fields need not be physically part of the nodes. If the data records are stored in an array and referenced by their indices, the link field may be stored in a separate array with the same indices as the data records.
List handles
Since a reference to the first node gives access to the whole list, that reference is often called the 'address', 'pointer', or 'handle' of the list. Algorithms that manipulate linked lists usually get such handles to the input lists and return the handles to the resulting lists. In fact, in the context of such algorithms, the word "list" often means "list handle". In some situations, however, it may be convenient to refer to a list by a handle that consists of two links, pointing to its first and last nodes.
Combining alternatives
The alternatives listed above may be arbitrarily combined in almost every way, so one may have circular doubly linked lists without sentinels, circular singly linked lists with sentinels, etc.
Tradeoffs
As with most choices in computer programming and design, no method is well suited to all circumstances. A linked list data structure might work well in one case, but cause problems in another. This is a list of some of the common tradeoffs involving linked list structures.
Linked lists vs. dynamic arrays
A ''
dynamic array
In computer science, a dynamic array, growable array, resizable array, dynamic table, mutable array, or array list is a random access, variable-size list data structure that allows elements to be added or removed. It is supplied with standard lib ...
'' is a data structure that allocates all elements contiguously in memory, and keeps a count of the current number of elements. If the space reserved for the dynamic array is exceeded, it is reallocated and (possibly) copied, which is an expensive operation.
Linked lists have several advantages over dynamic arrays. Insertion or deletion of an element at a specific point of a list, assuming that we have indexed a pointer to the node (before the one to be removed, or before the insertion point) already, is a constant-time operation (otherwise without this reference it is O(n)), whereas insertion in a dynamic array at random locations will require moving half of the elements on average, and all the elements in the worst case. While one can "delete" an element from an array in constant time by somehow marking its slot as "vacant", this causes
fragmentation that impedes the performance of iteration.
Moreover, arbitrarily many elements may be inserted into a linked list, limited only by the total memory available; while a dynamic array will eventually fill up its underlying array data structure and will have to reallocate—an expensive operation, one that may not even be possible if memory is fragmented, although the cost of reallocation can be averaged over insertions, and the cost of an insertion due to reallocation would still be
amortized
In computer science, amortized analysis is a method for analyzing a given algorithm's complexity, or how much of a resource, especially time or memory, it takes to execute. The motivation for amortized analysis is that looking at the worst-case ...
O(1). This helps with appending elements at the array's end, but inserting into (or removing from) middle positions still carries prohibitive costs due to data moving to maintain contiguity. An array from which many elements are removed may also have to be resized in order to avoid wasting too much space.
On the other hand, dynamic arrays (as well as fixed-size
array data structure
In computer science, an array is a data structure consisting of a collection of ''elements'' (values or variables), each identified by at least one ''array index'' or ''key''. An array is stored such that the position of each element can be co ...
s) allow constant-time
random access
Random access (more precisely and more generally called direct access) is the ability to access an arbitrary element of a sequence in equal time or any datum from a population of addressable elements roughly as easily and efficiently as any othe ...
, while linked lists allow only
sequential access
Sequential access is a term describing a group of elements (such as data in a memory array or a disk file or on magnetic tape data storage) being accessed in a predetermined, ordered sequence. It is the opposite of random access, the ability to ...
to elements. Singly linked lists, in fact, can be easily traversed in only one direction. This makes linked lists unsuitable for applications where it's useful to look up an element by its index quickly, such as
heapsort
In computer science, heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as an improved selection sort: like selection sort, heapsort divides its input into a sorted and an unsorted region, and it iteratively shrinks the ...
. Sequential access on arrays and dynamic arrays is also faster than on linked lists on many machines, because they have optimal
locality of reference
In computer science, locality of reference, also known as the principle of locality, is the tendency of a processor to access the same set of memory locations repetitively over a short period of time. There are two basic types of reference localit ...
and thus make good use of data caching.
Another disadvantage of linked lists is the extra storage needed for references, which often makes them impractical for lists of small data items such as
characters
Character or Characters may refer to:
Arts, entertainment, and media Literature
* ''Character'' (novel), a 1936 Dutch novel by Ferdinand Bordewijk
* ''Characters'' (Theophrastus), a classical Greek set of character sketches attributed to The ...
or
boolean value
In mathematics and mathematical logic, Boolean algebra is a branch of algebra. It differs from elementary algebra in two ways. First, the values of the variables are the truth values ''true'' and ''false'', usually denoted 1 and 0, whereas in ...
s, because the storage overhead for the links may exceed by a factor of two or more the size of the data. In contrast, a dynamic array requires only the space for the data itself (and a very small amount of control data).
[The amount of control data required for a dynamic array is usually of the form , where is a per-array constant, is a per-dimension constant, and is the number of dimensions. and are typically on the order of 10 bytes.] It can also be slow, and with a naïve allocator, wasteful, to allocate memory separately for each new element, a problem generally solved using
memory pool
Memory pools, also called fixed-size blocks allocation, is the use of pools for memory management that allows dynamic memory allocation comparable to malloc or C++'s operator new. As those implementations suffer from fragmentation because ...
s.
Some hybrid solutions try to combine the advantages of the two representations.
Unrolled linked lists store several elements in each list node, increasing cache performance while decreasing memory overhead for references.
CDR coding
In computer science CDR coding is a compressed data representation for Lisp linked lists. It was developed and patented by the MIT Artificial Intelligence Laboratory, and implemented in computer hardware in a number of Lisp machines derived from t ...
does both these as well, by replacing references with the actual data referenced, which extends off the end of the referencing record.
A good example that highlights the pros and cons of using dynamic arrays vs. linked lists is by implementing a program that resolves the
Josephus problem. The Josephus problem is an election method that works by having a group of people stand in a circle. Starting at a predetermined person, one may count around the circle ''n'' times. Once the ''n''th person is reached, one should remove them from the circle and have the members close the circle. The process is repeated until only one person is left. That person wins the election. This shows the strengths and weaknesses of a linked list vs. a dynamic array, because if the people are viewed as connected nodes in a circular linked list, then it shows how easily the linked list is able to delete nodes (as it only has to rearrange the links to the different nodes). However, the linked list will be poor at finding the next person to remove and will need to search through the list until it finds that person. A dynamic array, on the other hand, will be poor at deleting nodes (or elements) as it cannot remove one node without individually shifting all the elements up the list by one. However, it is exceptionally easy to find the ''n''th person in the circle by directly referencing them by their position in the array.
The
list ranking In parallel algorithms, the list ranking problem involves determining the position, or rank, of each item in a linked list. That is, the first item in the list should be assigned the number 1, the second item in the list should be assigned the numb ...
problem concerns the efficient conversion of a linked list representation into an array. Although trivial for a conventional computer, solving this problem by a
parallel algorithm
In computer science, a parallel algorithm, as opposed to a traditional serial algorithm, is an algorithm which can do multiple operations in a given time. It has been a tradition of computer science to describe serial algorithms in abstract machin ...
is complicated and has been the subject of much research.
A
balanced tree
In computer science, a self-balancing binary search tree (BST) is any node-based binary search tree that automatically keeps its height (maximal number of levels below the root) small in the face of arbitrary item insertions and deletions.Donald ...
has similar memory access patterns and space overhead to a linked list while permitting much more efficient indexing, taking O(log n) time instead of O(n) for a random access. However, insertion and deletion operations are more expensive due to the overhead of tree manipulations to maintain balance. Schemes exist for trees to automatically maintain themselves in a balanced state:
AVL tree
In computer science, an AVL tree (named after inventors Adelson-Velsky and Landis) is a self-balancing binary search tree. It was the first such data structure to be invented. In an AVL tree, the heights of the two child subtrees of any nod ...
s or
red–black trees.
Singly linked linear lists vs. other lists
While doubly linked and circular lists have advantages over singly linked linear lists, linear lists offer some advantages that make them preferable in some situations.
A singly linked linear list is a
recursive
Recursion (adjective: ''recursive'') occurs when a thing is defined in terms of itself or of its type. Recursion is used in a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in mathematics ...
data structure, because it contains a pointer to a ''smaller'' object of the same type. For that reason, many operations on singly linked linear lists (such as
merging
Merge, merging, or merger may refer to:
Concepts
* Merge (traffic), the reduction of the number of lanes on a road
* Merge (linguistics), a basic syntactic operation in generative syntax in the Minimalist Program
* Merger (politics), the comb ...
two lists, or enumerating the elements in reverse order) often have very simple recursive algorithms, much simpler than any solution using
iterative commands. While those recursive solutions can be adapted for doubly linked and circularly linked lists, the procedures generally need extra arguments and more complicated base cases.
Linear singly linked lists also allow
tail-sharing
In computer science, a linked list is a linear collection of data elements whose order is not given by their physical placement in memory. Instead, each element points to the next. It is a data structure consisting of a collection of nodes whic ...
, the use of a common final portion of sub-list as the terminal portion of two different lists. In particular, if a new node is added at the beginning of a list, the former list remains available as the tail of the new one—a simple example of a
persistent data structure
In computing, a persistent data structure or not ephemeral data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (v ...
. Again, this is not true with the other variants: a node may never belong to two different circular or doubly linked lists.
In particular, end-sentinel nodes can be shared among singly linked non-circular lists. The same end-sentinel node may be used for ''every'' such list. In
Lisp
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lisping ...
, for example, every proper list ends with a link to a special node, denoted by
nil
or
()
, whose
CAR
A car or automobile is a motor vehicle with wheels. Most definitions of ''cars'' say that they run primarily on roads, seat one to eight people, have four wheels, and mainly transport people instead of goods.
The year 1886 is regarded as ...
and
CDR
links point to itself. Thus a Lisp procedure can safely take the
CAR
or
CDR
of ''any'' list.
The advantages of the fancy variants are often limited to the complexity of the algorithms, not in their efficiency. A circular list, in particular, can usually be emulated by a linear list together with two variables that point to the first and last nodes, at no extra cost.
Doubly linked vs. singly linked
Double-linked lists require more space per node (unless one uses
XOR-linking), and their elementary operations are more expensive; but they are often easier to manipulate because they allow fast and easy sequential access to the list in both directions. In a doubly linked list, one can insert or delete a node in a constant number of operations given only that node's address. To do the same in a singly linked list, one must have the ''address of the pointer'' to that node, which is either the handle for the whole list (in case of the first node) or the link field in the ''previous'' node. Some algorithms require access in both directions. On the other hand, doubly linked lists do not allow tail-sharing and cannot be used as
persistent data structure
In computing, a persistent data structure or not ephemeral data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (v ...
s.
Circularly linked vs. linearly linked
A circularly linked list may be a natural option to represent arrays that are naturally circular, e.g. the corners of a
polygon
In geometry, a polygon () is a plane figure that is described by a finite number of straight line segments connected to form a closed ''polygonal chain'' (or ''polygonal circuit''). The bounded plane region, the bounding circuit, or the two toge ...
, a pool of
buffers that are used and released in
FIFO ("first in, first out") order, or a set of processes that should be
time-shared in
round-robin order. In these applications, a pointer to any node serves as a handle to the whole list.
With a circular list, a pointer to the last node gives easy access also to the first node, by following one link. Thus, in applications that require access to both ends of the list (e.g., in the implementation of a queue), a circular structure allows one to handle the structure by a single pointer, instead of two.
A circular list can be split into two circular lists, in constant time, by giving the addresses of the last node of each piece. The operation consists in swapping the contents of the link fields of those two nodes. Applying the same operation to any two nodes in two distinct lists joins the two list into one. This property greatly simplifies some algorithms and data structures, such as the
quad-edge
A quad-edge data structure is a computer representation of the topology of a dimension, two-dimensional or three-dimensional CW complex, map, that is, a graph theory, graph drawn on a (closed) Surface (topology), surface. It was first described by ...
and
face-edge.
The simplest representation for an empty ''circular'' list (when such a thing makes sense) is a null pointer, indicating that the list has no nodes. Without this choice, many algorithms have to test for this special case, and handle it separately. By contrast, the use of null to denote an empty ''linear'' list is more natural and often creates fewer special cases.
For some applications, it can be useful to use singly linked lists that can vary between being circular and being linear, or even circular with a linear initial segment. Algorithms for searching or otherwise operating on these have to take precautions to avoid accidentally entering an endless loop. One
well-known method is to have a second pointer walking the list at half or double the speed, and if both pointers meet at the same node, you know you found a cycle.
Using sentinel nodes
Sentinel node
In computer programming, a sentinel node is a specifically designated node used with linked lists and trees as a traversal path terminator. This type of node does not hold or reference any data managed by the data structure.
Benefits
Sentinel ...
may simplify certain list operations, by ensuring that the next or previous nodes exist for every element, and that even empty lists have at least one node. One may also use a sentinel node at the end of the list, with an appropriate data field, to eliminate some end-of-list tests. For example, when scanning the list looking for a node with a given value ''x'', setting the sentinel's data field to ''x'' makes it unnecessary to test for end-of-list inside the loop. Another example is the merging two sorted lists: if their sentinels have data fields set to +∞, the choice of the next output node does not need special handling for empty lists.
However, sentinel nodes use up extra space (especially in applications that use many short lists), and they may complicate other operations (such as the creation of a new empty list).
However, if the circular list is used merely to simulate a linear list, one may avoid some of this complexity by adding a single sentinel node to every list, between the last and the first data nodes. With this convention, an empty list consists of the sentinel node alone, pointing to itself via the next-node link. The list handle should then be a pointer to the last data node, before the sentinel, if the list is not empty; or to the sentinel itself, if the list is empty.
The same trick can be used to simplify the handling of a doubly linked linear list, by turning it into a circular doubly linked list with a single sentinel node. However, in this case, the handle should be a single pointer to the dummy node itself.
Linked list operations
When manipulating linked lists in-place, care must be taken to not use values that you have invalidated in previous assignments. This makes algorithms for inserting or deleting linked list nodes somewhat subtle. This section gives
pseudocode
In computer science, pseudocode is a plain language description of the steps in an algorithm or another system. Pseudocode often uses structural conventions of a normal programming language, but is intended for human reading rather than machine re ...
for adding or removing nodes from singly, doubly, and circularly linked lists in-place. Throughout we will use ''null'' to refer to an end-of-list marker or
sentinel
Sentinel may refer to:
Places Mountains
* Mount Sentinel, a mountain next to the University of Montana in Missoula, Montana
* Sentinel Buttress, a volcanic crag on James Ross Island, Antarctica
* Sentinel Dome, a naturally occurring grani ...
, which may be implemented in a number of ways.
Linearly linked lists
Singly linked lists
Our node data structure will have two fields. We also keep a variable ''firstNode'' which always points to the first node in the list, or is ''null'' for an empty list.
record ''Node''
record ''List''
Traversal of a singly linked list is simple, beginning at the first node and following each ''next'' link until we come to the end:
node := list.firstNode
while node not null
''(do something with node.data)''
node := node.next
The following code inserts a node after an existing node in a singly linked list. The diagram shows how it works. Inserting a node before an existing one cannot be done directly; instead, one must keep track of the previous node and insert a node after it.
![CPT-LinkedLists-addingnode](https://upload.wikimedia.org/wikipedia/commons/4/4b/CPT-LinkedLists-addingnode.svg)
function insertAfter(''Node'' node, ''Node'' newNode) ''// insert newNode after node''
newNode.next := node.next
node.next := newNode
Inserting at the beginning of the list requires a separate function. This requires updating ''firstNode''.
function insertBeginning(''List'' list, ''Node'' newNode) ''// insert node before current first node''
newNode.next := list.firstNode
list.firstNode := newNode
Similarly, we have functions for removing the node ''after'' a given node, and for removing a node from the beginning of the list. The diagram demonstrates the former. To find and remove a particular node, one must again keep track of the previous element.
![CPT-LinkedLists-deletingnode](https://upload.wikimedia.org/wikipedia/commons/d/d4/CPT-LinkedLists-deletingnode.svg)
function removeAfter(''Node'' node) ''// remove node past this one''
obsoleteNode := node.next
node.next := node.next.next
destroy obsoleteNode
function removeBeginning(''List'' list) ''// remove first node''
obsoleteNode := list.firstNode
list.firstNode := list.firstNode.next ''// point past deleted node''
destroy obsoleteNode
Notice that
removeBeginning()
sets
list.firstNode
to
null
when removing the last node in the list.
Since we can't iterate backwards, efficient
insertBefore
or
removeBefore
operations are not possible. Inserting to a list before a specific node requires traversing the list, which would have a worst case running time of O(n).
Appending one linked list to another can be inefficient unless a reference to the tail is kept as part of the List structure, because we must traverse the entire first list in order to find the tail, and then append the second list to this. Thus, if two linearly linked lists are each of length
, list appending has
asymptotic time complexity of
. In the Lisp family of languages, list appending is provided by the
append
In computer programming, append is the operation for concatenating linked lists or arrays in some high-level programming languages.
Lisp
Append originates in the Lisp programming language. The append procedure takes zero or more (linked) lists a ...
procedure.
Many of the special cases of linked list operations can be eliminated by including a dummy element at the front of the list. This ensures that there are no special cases for the beginning of the list and renders both
insertBeginning()
and
removeBeginning()
unnecessary. In this case, the first useful data in the list will be found at
list.firstNode.next
.
Circularly linked list
In a circularly linked list, all nodes are linked in a continuous circle, without using ''null.'' For lists with a front and a back (such as a queue), one stores a reference to the last node in the list. The ''next'' node after the last node is the first node. Elements can be added to the back of the list and removed from the front in constant time.
Circularly linked lists can be either singly or doubly linked.
Both types of circularly linked lists benefit from the ability to traverse the full list beginning at any given node. This often allows us to avoid storing ''firstNode'' and ''lastNode'', although if the list may be empty we need a special representation for the empty list, such as a ''lastNode'' variable which points to some node in the list or is ''null'' if it's empty; we use such a ''lastNode'' here. This representation significantly simplifies adding and removing nodes with a non-empty list, but empty lists are then a special case.
Algorithms
Assuming that ''someNode'' is some node in a non-empty circular singly linked list, this code iterates through that list starting with ''someNode'':
function iterate(someNode)
if someNode ≠ null
node := someNode
do
do something with node.value
node := node.next
while node ≠ someNode
Notice that the test "while node ≠ someNode" must be at the end of the loop. If the test was moved to the beginning of the loop, the procedure would fail whenever the list had only one node.
This function inserts a node "newNode" into a circular linked list after a given node "node". If "node" is null, it assumes that the list is empty.
function insertAfter(''Node'' node, ''Node'' newNode)
if node = null // assume list is empty
newNode.next := newNode
else
newNode.next := node.next
node.next := newNode
update ''lastNode'' variable if necessary
Suppose that "L" is a variable pointing to the last node of a circular linked list (or null if the list is empty). To append "newNode" to the ''end'' of the list, one may do
insertAfter(L, newNode)
L := newNode
To insert "newNode" at the ''beginning'' of the list, one may do
insertAfter(L, newNode)
if L = null
L := newNode
This function inserts a value "newVal" before a given node "node" in O(1) time. We create a new node between "node" and the next node, and then put the value of "node" into that new node, and put "newVal" in "node". Thus, a singly linked circularly linked list with only a ''firstNode'' variable can both insert to the front and back in O(1) time.
function insertBefore(''Node'' node, newVal)
if node = null // assume list is empty
newNode := new Node(data:=newVal, next:=newNode)
else
newNode := new Node(data:=node.data, next:=node.next)
node.data := newVal
node.next := newNode
update ''firstNode'' variable if necessary
This function removes a non-null node from a list of size greater than 1 in O(1) time. It copies data from the next node into the node, and then sets the node's ''next'' pointer to skip over the next node.
function remove(''Node'' node)
if node ≠ null and size of list > 1
removedData := node.data
node.data := node.next.data
node.next = node.next.next
return removedData
Linked lists using arrays of nodes
Languages that do not support any type of
reference
Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a ''name'' ...
can still create links by replacing pointers with array indices. The approach is to keep an
array
An array is a systematic arrangement of similar objects, usually in rows and columns.
Things called an array include:
{{TOC right
Music
* In twelve-tone and serial composition, the presentation of simultaneous twelve-tone sets such that the ...
of
records, where each record has integer fields indicating the index of the next (and possibly previous) node in the array. Not all nodes in the array need be used. If records are also not supported,
parallel arrays can often be used instead.
As an example, consider the following linked list record that uses arrays instead of pointers:
record ''Entry''
A linked list can be built by creating an array of these structures, and an integer variable to store the index of the first element.
''integer'' listHead
''Entry'' Records
000
Triple zero, Triple Zero, Zero Zero Zero, Triple 0, Triple-0, 000, or 0-0-0 may refer to:
* 000 (emergency telephone number), the Australian emergency telephone number
* "Triple Zero", a song by AFI (band), AFI from ''Shut Your Mouth and Open Your ...
Links between elements are formed by placing the array index of the next (or previous) cell into the Next or Prev field within a given element. For example:
In the above example,
ListHead
would be set to 2, the location of the first entry in the list. Notice that entry 3 and 5 through 7 are not part of the list. These cells are available for any additions to the list. By creating a
ListFree
integer variable, a
free list
A free list (or freelist) is a data structure used in a scheme for dynamic memory allocation. It operates by connecting unallocated regions of memory together in a linked list, using the first word of each unallocated region as a pointer to the n ...
could be created to keep track of what cells are available. If all entries are in use, the size of the array would have to be increased or some elements would have to be deleted before new entries could be stored in the list.
The following code would traverse the list and display names and account balance:
i := listHead
while i ≥ 0 ''// loop through the list''
print i, Records
name, Records
balance ''// print entry''
i := Records
next
When faced with a choice, the advantages of this approach include:
* The linked list is relocatable, meaning it can be moved about in memory at will, and it can also be quickly and directly
serialized for storage on disk or transfer over a network.
* Especially for a small list, array indexes can occupy significantly less space than a full pointer on many architectures.
*
Locality of reference
In computer science, locality of reference, also known as the principle of locality, is the tendency of a processor to access the same set of memory locations repetitively over a short period of time. There are two basic types of reference localit ...
can be improved by keeping the nodes together in memory and by periodically rearranging them, although this can also be done in a general store.
* Naïve
dynamic memory allocators can produce an excessive amount of overhead storage for each node allocated; almost no allocation overhead is incurred per node in this approach.
* Seizing an entry from a pre-allocated array is faster than using dynamic memory allocation for each node, since dynamic memory allocation typically requires a search for a free memory block of the desired size.
This approach has one main disadvantage, however: it creates and manages a private memory space for its nodes. This leads to the following issues:
* It increases complexity of the implementation.
* Growing a large array when it is full may be difficult or impossible, whereas finding space for a new linked list node in a large, general memory pool may be easier.
* Adding elements to a dynamic array will occasionally (when it is full) unexpectedly take linear (
O(n)) instead of constant time (although it's still an
amortized
In computer science, amortized analysis is a method for analyzing a given algorithm's complexity, or how much of a resource, especially time or memory, it takes to execute. The motivation for amortized analysis is that looking at the worst-case ...
constant).
* Using a general memory pool leaves more memory for other data if the list is smaller than expected or if many nodes are freed.
For these reasons, this approach is mainly used for languages that do not support dynamic memory allocation. These disadvantages are also mitigated if the maximum size of the list is known at the time the array is created.
Language support
Many
programming language
A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are a kind of computer language.
The description of a programming ...
s such as
Lisp
A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech.
Types
* A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lisping ...
and
Scheme A scheme is a systematic plan for the implementation of a certain idea.
Scheme or schemer may refer to:
Arts and entertainment
* ''The Scheme'' (TV series), a BBC Scotland documentary series
* The Scheme (band), an English pop band
* ''The Schem ...
have singly linked lists built in. In many
functional languages
In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that m ...
, these lists are constructed from nodes, each called a ''
cons
In computer programming, ( or ) is a fundamental function in most dialects of the Lisp programming language. ''constructs'' memory objects which hold two values or pointers to two values. These objects are referred to as (cons) cells, conses, ...
'' or ''cons cell''. The cons has two fields: the ''
car
A car or automobile is a motor vehicle with wheels. Most definitions of ''cars'' say that they run primarily on roads, seat one to eight people, have four wheels, and mainly transport people instead of goods.
The year 1886 is regarded as ...
'', a reference to the data for that node, and the ''
cdr'', a reference to the next node. Although cons cells can be used to build other data structures, this is their primary purpose.
In languages that support
abstract data type
In computer science, an abstract data type (ADT) is a mathematical model for data types. An abstract data type is defined by its behavior (semantics) from the point of view of a ''user'', of the data, specifically in terms of possible values, pos ...
s or templates, linked list ADTs or templates are available for building linked lists. In other languages, linked lists are typically built using
reference
Reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a ''name'' ...
s together with
records.
Internal and external storage
When constructing a linked list, one is faced with the choice of whether to store the data of the list directly in the linked list nodes, called ''internal storage'', or merely to store a reference to the data, called ''external storage''. Internal storage has the advantage of making access to the data more efficient, requiring less storage overall, having better
locality of reference
In computer science, locality of reference, also known as the principle of locality, is the tendency of a processor to access the same set of memory locations repetitively over a short period of time. There are two basic types of reference localit ...
, and simplifying memory management for the list (its data is allocated and deallocated at the same time as the list nodes).
External storage, on the other hand, has the advantage of being more generic, in that the same data structure and machine code can be used for a linked list no matter what the size of the data is. It also makes it easy to place the same data in multiple linked lists. Although with internal storage the same data can be placed in multiple lists by including multiple ''next'' references in the node data structure, it would then be necessary to create separate routines to add or delete cells based on each field. It is possible to create additional linked lists of elements that use internal storage by using external storage, and having the cells of the additional linked lists store references to the nodes of the linked list containing the data.
In general, if a set of data structures needs to be included in linked lists, external storage is the best approach. If a set of data structures need to be included in only one linked list, then internal storage is slightly better, unless a generic linked list package using external storage is available. Likewise, if different sets of data that can be stored in the same data structure are to be included in a single linked list, then internal storage would be fine.
Another approach that can be used with some languages involves having different data structures, but all have the initial fields, including the ''next'' (and ''prev'' if double linked list) references in the same location. After defining separate structures for each type of data, a generic structure can be defined that contains the minimum amount of data shared by all the other structures and contained at the top (beginning) of the structures. Then generic routines can be created that use the minimal structure to perform linked list type operations, but separate routines can then handle the specific data. This approach is often used in message parsing routines, where several types of messages are received, but all start with the same set of fields, usually including a field for message type. The generic routines are used to add new messages to a queue when they are received, and remove them from the queue in order to process the message. The message type field is then used to call the correct routine to process the specific type of message.
Example of internal and external storage
Suppose you wanted to create a linked list of families and their members. Using internal storage, the structure might look like the following:
record ''member''
record ''family''
To print a complete list of families and their members using internal storage, we could write:
aFamily := Families ''// start at head of families list''
while aFamily ≠ null ''// loop through list of families''
print information about family
aMember := aFamily.members ''// get head of list of this family's members''
while aMember ≠ null ''// loop through list of members''
print information about member
aMember := aMember.next
aFamily := aFamily.next
Using external storage, we would create the following structures:
record ''node''
record ''member''
record ''family''
To print a complete list of families and their members using external storage, we could write:
famNode := Families ''// start at head of families list''
while famNode ≠ null ''// loop through list of families''
aFamily := (family) famNode.data ''// extract family from node''
print information about family
memNode := aFamily.members ''// get list of family members''
while memNode ≠ null ''// loop through list of members''
aMember := (member)memNode.data ''// extract member from node''
print information about member
memNode := memNode.next
famNode := famNode.next
Notice that when using external storage, an extra step is needed to extract the record from the node and cast it into the proper data type. This is because both the list of families and the list of members within the family are stored in two linked lists using the same data structure (''node''), and this language does not have parametric types.
As long as the number of families that a member can belong to is known at compile time, internal storage works fine. If, however, a member needed to be included in an arbitrary number of families, with the specific number known only at run time, external storage would be necessary.
Speeding up search
Finding a specific element in a linked list, even if it is sorted, normally requires O(''n'') time (
linear search
In computer science, a linear search or sequential search is a method for finding an element within a list. It sequentially checks each element of the list until a match is found or the whole list has been searched.
A linear search runs in at ...
). This is one of the primary disadvantages of linked lists over other data structures. In addition to the variants discussed above, below are two simple ways to improve search time.
In an unordered list, one simple heuristic for decreasing average search time is the ''move-to-front heuristic'', which simply moves an element to the beginning of the list once it is found. This scheme, handy for creating simple caches, ensures that the most recently used items are also the quickest to find again.
Another common approach is to "
index
Index (or its plural form indices) may refer to:
Arts, entertainment, and media Fictional entities
* Index (''A Certain Magical Index''), a character in the light novel series ''A Certain Magical Index''
* The Index, an item on a Halo megastru ...
" a linked list using a more efficient external data structure. For example, one can build a
red–black tree or
hash table
In computing, a hash table, also known as hash map, is a data structure that implements an associative array or dictionary. It is an abstract data type that maps keys to values. A hash table uses a hash function to compute an ''index'', als ...
whose elements are references to the linked list nodes. Multiple such indexes can be built on a single list. The disadvantage is that these indexes may need to be updated each time a node is added or removed (or at least, before that index is used again).
Random-access lists
A
random-access list is a list with support for fast random access to read or modify any element in the list.
One possible implementation is a
skew binary random-access list using the
skew binary number system
Skew may refer to:
In mathematics
* Skew lines, neither parallel nor intersecting.
* Skew normal distribution, a probability distribution
* Skew field or division ring
* Skew-Hermitian matrix
* Skew lattice
* Skew polygon, whose vertices do not l ...
, which involves a list of trees with special properties; this allows worst-case constant time head/cons operations, and worst-case logarithmic time random access to an element by index.
Random-access lists can be implemented as
persistent data structure
In computing, a persistent data structure or not ephemeral data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (v ...
s.
Random-access lists can be viewed as immutable linked lists in that they likewise support the same O(1) head and tail operations.
A simple extension to random-access lists is the
min-list, which provides an additional operation that yields the minimum element in the entire list in constant time (without mutation complexities).
Related data structures
Both
stacks and
queues are often implemented using linked lists, and simply restrict the type of operations which are supported.
The
skip list
In computer science, a skip list (or skiplist) is a probabilistic data structure that allows \mathcal(\log n) average complexity for search as well as \mathcal(\log n) average complexity for insertion within an ordered sequence of n elements. T ...
is a linked list augmented with layers of pointers for quickly jumping over large numbers of elements, and then descending to the next layer. This process continues down to the bottom layer, which is the actual list.
A
binary tree
In computer science, a binary tree is a k-ary k = 2 tree data structure in which each node has at most two children, which are referred to as the ' and the '. A recursive definition using just set theory notions is that a (non-empty) binary t ...
can be seen as a type of linked list where the elements are themselves linked lists of the same nature. The result is that each node may include a reference to the first node of one or two other linked lists, which, together with their contents, form the subtrees below that node.
An
unrolled linked list is a linked list in which each node contains an array of data values. This leads to improved
cache
Cache, caching, or caché may refer to:
Places United States
* Cache, Idaho, an unincorporated community
* Cache, Illinois, an unincorporated community
* Cache, Oklahoma, a city in Comanche County
* Cache, Utah, Cache County, Utah
* Cache County ...
performance, since more list elements are contiguous in memory, and reduced memory overhead, because less metadata needs to be stored for each element of the list.
A
hash table
In computing, a hash table, also known as hash map, is a data structure that implements an associative array or dictionary. It is an abstract data type that maps keys to values. A hash table uses a hash function to compute an ''index'', als ...
may use linked lists to store the chains of items that hash to the same position in the hash table.
A
heap shares some of the ordering properties of a linked list, but is almost always implemented using an array. Instead of references from node to node, the next and previous data indexes are calculated using the current data's index.
A
self-organizing list A self-organizing list is a list that reorders its elements based on some self-organizing heuristic to improve average access time. The aim of a self-organizing list is to improve efficiency of linear search by moving more frequently accessed items ...
rearranges its nodes based on some heuristic which reduces search times for data retrieval by keeping commonly accessed nodes at the head of the list.
Notes
References
Further reading
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
External links
Descriptionfrom the
Dictionary of Algorithms and Data Structures
The NIST ''Dictionary of Algorithms and Data Structures'' is a reference work maintained by the U.S. National Institute of Standards and Technology. It defines a large number of terms relating to algorithms and data structures. For algorithms and ...
Introduction to Linked Lists Stanford University Computer Science Library
Linked List Problems Stanford University Computer Science Library
Pat Morin
Patrick Ryan Morin is a Canadian computer scientist specializing in computational geometry and data structures. He is a professor in the School of Computer Science at Carleton University.
Education and career
Morin was educated at Carleton Univers ...
Patent for the idea of having nodes which are in several linked lists simultaneously(note that this technique was widely used for many decades before the patent was granted)
{{Authority control
Articles with example C code