Anda di halaman 1dari 17

Concept of Linked list

Linked lists were developed in 19551956 by Allen Newell,


Cliff Shaw and Herbert A. Simon at RAND Corporation as the
primary data structure for their Information Processing
Language. IPL was used by the authors to develop several
early artificial intelligence programs, including the Logic
Theory Machine, the General Problem Solver, 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 International Conference on Information
Processing) in 1959.

In computer science, a linked list is a linear collection of data


elements, called nodes, each pointing to the next node by
means of a pointer. It is a data structure consisting of a
group of nodes which together represent a sequence. Under
the simplest form, each node is composed of data and a
reference (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 efficient insertion or removal from arbitrary element
references.
Linked lists are among the simplest and most common data
structures. They can be used to implement several other
common abstract data types, including lists (the abstract
data type), stacks, queues, associative arrays, and S-
expressions, though it is not uncommon to implement the
other data structures directly without using a list as the basis
of implementation.
The principal benefit of a linked list over a
conventional array is that the list elements can easily be
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 an array has
to be declared in the source code, before compiling and
running the program. Linked lists allow insertion and
removal of nodes at any point in the list, and can do so with a
constant number of operations if the link previous to the link
being added or removed is maintained during list traversal.
On the other hand, simple linked lists by themselves do not
allow random access to the data, or any form of efficient
indexing. Thus, many basic operations such as obtaining
the last node of the list (assuming that the last node is not
maintained as separate node reference in the list structure),
or finding a node that contains a given datum, or locating the
place where a new node should be inserted may require
sequential scanning of most or all of the list elements. The
advantages and disadvantages of using linked lists are given
below.
Advantages

Linked lists are a dynamic data structure, which can


grow and be pruned, allocating and deallocating
memory while the program is running.
Insertion and deletion node operations are easily
implemented in a linked list.
Dynamic data structures such as stacks and queues can
be implemented using a linked list.
There is no need to define an initial size for a Linked list.
Items can be added or removed from the middle of list.

Disadvantages

They use more memory than arrays because of the


storage used by their pointers.
Nodes in a linked list must be read in order from the
beginning as linked lists are inherently sequential access.
Nodes are stored incontiguously, greatly increasing the
time required to access individual elements within the list,
especially with a CPU cache.
Difficulties arise in linked lists when it comes to reverse
traversing. For instance, singly linked lists are
cumbersome to navigate backwards[1] and while doubly
linked lists are somewhat easier to read, memory is
consumed in allocating space for a back-pointer.

Speeding up search

Finding a specific element in a linked list, even if it is sorted,


normally requires O(n) time (linear search). 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" a linked list using a


more efficient external data structure. For example, one can
build a red-black tree or hash table 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).

Concept of Sack

Stacks entered the computer science literature in 1946, in the


computer design of Alan M. Turing (who used the terms
"bury" and "unbury") as a means of calling and returning
from subroutines.[2][clarification needed] Subroutines had
already been implemented in Konrad Zuse's Z4 in 1945.
Klaus Samelson and Friedrich L. Bauer of Technical
University Munich proposed the idea in 1955 and filed a
patent in 1957. The same concept was developed,
independently, by the Australian Charles Leonard Hamblin in
the first half of 1957 .

Stacks are often described by analogy to a spring-loaded


stack of plates in a cafeteria. Clean plates are placed on top
of the stack, pushing down any already there. When a plate is
removed from the stack, the one below it pops up to become
the new top.
In computer science, a stack is an abstract data type that
serves as a collection of elements, with two principal
operations: push, which adds an element to the collection,
and pop, which removes the most recently added element
that was not yet removed. The order in which elements come
off a stack gives rise to its alternative name, LIFO (for last in,
first out). Additionally, a peek operation may give access to
the top without modifying the stack.
The name "stack" for this type of structure comes from the
analogy to a set of physical items stacked on top of each
other, which makes it easy to take an item off the top of the
stack, while getting to an item deeper in the stack may
require taking off multiple other items first
Considered as a linear data structure, or more abstractly a
sequential collection, the push and pop operations occur
only at one end of the structure, referred to as the top of the
stack. This makes it possible to implement a stack as a
singly linked list and a pointer to the top element.
A stack may be implemented to have a bounded capacity. If
the stack is full and does not contain enough space to accept
an entity to be pushed, the stack is then considered to be in
an overflow state. The pop operation removes an item from
the top of the stack.

Non-essential operations
In many implementations, a stack has more operations than
"push" and "pop". An example is "top of stack", or "peek",
which observes the top-most element without removing it
from the stack.[7] Since this can be done with a "pop" and a
"push" with the same data, it is not essential. An underflow
condition can occur in the "stack top" operation if the stack
is empty, the same as "pop". Also, implementations often
have a function which just returns whether the stack is
empty.
Runtime memory management

Main articles: Stack-based memory allocation and Stack


machine
A number of programming languages are stack-oriented,
meaning they define most basic operations (adding two
numbers, printing a character) as taking their arguments
from the stack, and placing any return values back on the
stack. For example, PostScript has a return stack and an
operand stack, and also has a graphics state stack and a
dictionary stack. Many virtual machines are also stack-
oriented, including the p-code machine and the Java Virtual
Machine.

Almost all calling conventionsthe ways in which


subroutines receive their parameters and return resultsuse
a special stack (the "call stack") to hold information about
procedure/function calling and nesting in order to switch to
the context of the called function and restore to the caller
function when the calling finishes. The functions follow a
runtime protocol between caller and callee to save
arguments and return value on the stack. Stacks are an
important way of supporting nested or recursive function
calls. This type of stack is used implicitly by the compiler to
support CALL and RETURN statements (or their equivalents)
and is not manipulated directly by the programmer.
Some programming languages use the stack to store data
that is local to a procedure. Space for local data items is
allocated from the stack when the procedure is entered, and
is deallocated when the procedure exits. The C programming
language is typically implemented in this way. Using the
same stack for both data and procedure calls has important
security implications (see below) of which a programmer
must be aware in order to avoid introducing serious security
bugs into a program.

Efficient algorithms

Several algorithms use a stack (separate from the usual


function call stack of most programming languages) as the
principle data structure with which they organize their
information. These include:

Graham scan, an algorithm for the convex hull of a two-


dimensional system of points. A convex hull of a subset of
the input is maintained in a stack, which is used to find and
remove concavities in the boundary when a new point is
added to the hull.
Part of the SMAWK algorithm for finding the row minima of a
monotone matrix uses stacks in a similar way to Graham
scan.
All nearest smaller values, the problem of finding, for each
number in an array, the closest preceding number that is
smaller than it. One algorithm for this problem uses a stack
to maintain a collection of candidates for the nearest smaller
value. For each position in the array, the stack is popped
until a smaller value is found on its top, and then the value in
the new position is pushed onto the stack. The nearest-
neighbor chain algorithm, a method for agglomerative
hierarchical clustering based on maintaining a stack of
clusters, each of which is the nearest neighbor of its
predecessor on the stack. When this method finds a pair of
clusters that are mutual nearest neighbors, they are popped
and merged.

Security
Some computing environments use stacks in ways that may
make them vulnerable to security breaches and attacks.
Programmers working in such environments must take
special care to avoid the pitfalls of these implementations.
For example, some programming languages use a common
stack to store both data local to a called procedure and the
linking information that allows the procedure to return to its
caller. This means that the program moves data into and out
of the same stack that contains critical return addresses for
the procedure calls. If data is moved to the wrong location on
the stack, or an oversized data item is moved to a stack
location that is not large enough to contain it, return
information for procedure calls may be corrupted, causing
the program to fail.
Malicious parties may attempt a stack smashing attack that
takes advantage of this type of implementation by providing
oversized data input to a program that does not check the
length of input. Such a program may copy the data in its
entirety to a location on the stack, and in so doing it may
change the return addresses for procedures that have called
it. An attacker can experiment to find a specific type of data
that can be provided to such a program such that the return
address of the current procedure is reset to point to an area
within the stack itself (and within the data provided by the
attacker), which in turn contains instructions that carry out
unauthorized operations.
This type of attack is a variation on the buffer overflow attack
and is an extremely frequent source of security breaches in
software, mainly because some of the most popular
compilers use a shared stack for both data and procedure
calls, and do not verify the length of data items. Frequently
programmers do not write code to verify the size of data
items, either, and when an oversized or undersized data item
is copied to the stack, a security breach may occur.

Concept of Queue

In computer science, a queue (/kju/ kyew) is a particular


kind of abstract data type or collection in which the entities
in the collection are kept in order and the principal (or only)
operations on the collection are the addition of entities to the
rear terminal position, known as enqueue, and removal of
entities from the front terminal position, known as dequeue.
This makes the queue a First-In-First-Out (FIFO) data
structure. In a FIFO data structure, the first element added to
the queue will be the first one to be removed. This is
equivalent to the requirement that once a new element is
added, all elements that were added before have to be
removed before the new element can be removed. Often a
peek or front operation is also entered, returning the value of
the front element without dequeuing it. A queue is an
example of a linear data structure, or more abstractly a
sequential collection.
Queues provide services in computer science, transport, and
operations research where various entities such as data,
objects, persons, or events are stored and held to be
processed later. In these contexts, the queue performs the
function of a buffer.
Queues are common in computer programs, where they are
implemented as data structures coupled with access
routines, as an abstract data structure or in object-oriented
languages as classes. Common implementations are circular
buffers and linked lists.
Queue implementation

Theoretically, one characteristic of a queue is that it does not


have a specific capacity. Regardless of how many elements
are already contained, a new element can always be added. It
can also be empty, at which point removing an element will
be impossible until a new element has been added again.

Fixed length arrays are limited in capacity, but it is not true


that items need to be copied towards the head of the queue.
The simple trick of turning the array into a closed circle and
letting the head and tail drift around endlessly in that circle
makes it unnecessary to ever move items stored in the array.
If n is the size of the array, then computing indices modulo n
will turn the array into a circle. This is still the conceptually
simplest way to construct a queue in a high level language,
but it does admittedly slow things down a little, because the
array indices must be compared to zero and the array size,
which is comparable to the time taken to check whether an
array index is out of bounds, which some languages do, but
this will certainly be the method of choice for a quick and
dirty implementation, or for any high level language that
does not have pointer syntax. The array size must be
declared ahead of time, but some implementations simply
double the declared array size when overflow occurs. Most
modern languages with objects or pointers can implement or
come with libraries for dynamic lists. Such data structures
may have not specified fixed capacity limit besides memory
constraints. Queue overflow results from trying to add an
element onto a full queue and queue underflow happens
when trying to remove an element from an empty queue.

A bounded queue is a queue limited to a fixed number of


items.

There are several efficient implementations of FIFO queues.


An efficient implementation is one that can perform the
operationsenqueuing and dequeuingin O(1) time.

Queues and programming languages

Queues may be implemented as a separate data type, or may


be considered a special case of a double-ended queue
(deque) and not implemented separately. For example, Perl
and Ruby allow pushing and popping an array from both
ends, so one can use push and shift functions to enqueue
and dequeue a list (or, in reverse, one can use unshift and
pop), although in some cases these operations are not
efficient.

C++'s Standard Template Library provides a "queue"


templated class which is restricted to only push/pop
operations. Since J2SE5.0, Java's library contains a Queue
interface that specifies queue operations; implementing
classes include LinkedList and (since J2SE 1.6) ArrayDeque.
PHP has an SplQueue class and third party libraries like
beanstalk'd and Gearman.

Concepts of Tree

In computer science, a tree is a widely used abstract data


type (ADT)or data structure implementing this ADTthat
simulates a hierarchical tree structure, with a root value and
subtrees of children with a parent node, represented as a set
of linked nodes.

A tree data structure can be defined recursively (locally) as a


collection of nodes (starting at a root node), where each
node is a data structure consisting of a value, together with a
list of references to nodes (the "children"), with the
constraints that no reference is duplicated, and none points
to the root.

Alternatively, a tree can be defined abstractly as a whole


(globally) as an ordered tree, with a value assigned to each
node. Both these perspectives are useful: while a tree can be
analyzed mathematically as a whole, when actually
represented as a data structure it is usually represented and
worked with separately by node (rather than as a list of
nodes and an adjacency list of edges between nodes, as one
may represent a digraph, for instance). For example, looking
at a tree as a whole, one can talk about "the parent node" of
a given node, but in general as a data structure a given node
only contains the list of its children, but does not contain a
reference to its parent (if any).

Concepts of Graph

In computer science, a graph is an abstract data type that is


meant to implement the undirected graph and directed graph
concepts from mathematics.

A graph data structure consists of a finite (and possibly


mutable) set of vertices or nodes or points, together with a
set of unordered pairs of these vertices for an undirected
graph or a set of ordered pairs for a directed graph. These
pairs are known as edges, arcs, or lines for an undirected
graph and as arrows, directed edges, directed arcs, or
directed lines for a directed graph. The vertices may be part
of the graph structure, or may be external entities
represented by integer indices or references.
A graph data structure may also associate to each edge
some edge value, such as a symbolic label or a numeric
attribute (cost, capacity, length, etc.).

In mathematics graph theory is the study of graphs, which


are mathematical structures used to model pairwise relations
between objects. A graph in this context is made up of
vertices, nodes, or points which are connected by edges,
arcs, or lines. A graph may be undirected, meaning that there
is no distinction between the two vertices associated with
each edge, or its edges may be directed from one vertex to
another; see Graph (discrete mathematics) for more detailed
definitions and for other variations in the types of graph that
are commonly considered. Graphs are one of the prime
objects of study in discrete mathematics.

Anda mungkin juga menyukai