Data Structures and
Algorithms
List ADT
An ADT – from the previous lecture
•An abstract data type (ADT) is:
•a collection of data, along with
•A set of operations on that data.
•Data structures specify a way to
organize our data in an ADT
•The operations that are supported by
the ADT are designed using Algorithms
Algorithm
•Typically, we represent the
implementation of an ADT operations by
the use of an algorithm
•An algorithm is a finite sequence of
instructions that specifies precisely how
an operation will be performed
•An algorithm can be expressed by
flowcharts or pseudocode
Pseudocode
• Pseudocode can be used to express algorithms in a
manner independent of a programming language
• Pseudocode is not meant to be compiled or
executed by the computer
• The reason for using pseudocode is to allow the
designer to convey basic ideas about an algorithm
in general terms
Pseudocode (2)
• Pseudocode allows us to represent
algorithms without worrying about
implementation details
• This facilitates the analysis of algorithms
• Pseudocode consists of keywords and
English-like phrases that are indented to
indicate flow of control
The List ADT
• A list is an ordered set of elements i.e.
L = (l1, l2, …, ln)
• where li is the i-th element of the list
• The elements of the list have a linear ordering based on the position in the
list
• we say li+1 follows (succeeds) li and li-1 precedes li
• The first element in the list l1, is referred to as the head, while the last
element ln is the tail.
• The length of the list is given by |L|.
Defining the List ADT
• What data are required?
• “Items” of a particular data type.
• Let’s define the items to be of type ItemType
What operations are required?
• Create an empty list
• Destroy a list
• Determine the number of items in a list
• Insert an item at a given position in a list
• Remove the item at a given position in a list
• Retrieve the item at a given position in a list
Formal Definition of Operations
• createList(L). Create an empty list
• makeEmpty(L). Destroy a list L
• insert(L, x, i). Adds element x at position i in the of list L
• Append(L, x). Adds element x to the tail of list L
• retrieve (L, i). Returns the element stored at position i of L or
null if position doesn’t exist
• delete(L, i). deletes the element stored at position i of L.
• this causes element Ii+1….n to become I I ……I
1, i+1 n
• Length of the list becomes Length-1
• length(L). Returns the length of list |L|
Example
• Consider the List L = (dog, cat,
rat, bat)
1. insert (L, pig, 2)
2. insert (L, cow, 4)
3. append (L, hen)
4. delete (L, rat)
5. retrieve (L, 3)
Implementing a List
• There are two fundamental ways of storing
structures in a computers memory, namely:
1. Sequential storage
• Each element of the structure is stored next to the other.
This is also called array-based implementation
2. Linked storage
• Each element of the structure may be stored anywhere in
memory. This requires that we explicitly store in each
element the address of the next element using a pointer.
Also called pointer implementation
Array-Based List Implementation
• By allocating an array of memory at compile time, we can
create a list of elements.
l1 l2 l3 …. ln ….
List[0] List[1] List[2] List[n]
The structure can be defines as
#define MAXLEN = 100
typedef int itemType;
typedef struct {
itemType List [MAXLEN]; /* array of list items */
int length; /* number of items in the list */
} List;
Implementing Operations (3)
1.Insertion Operation
•Inserting at the head of the list requires first pushing
the entire array one step to make room for the new
element
a1 a2 a3 a4 …. an
0 1 2 3 n-1
insert(L,0,x)
a1 a2 a3 a4 …. an
0 1 2 3 n-1
x a1 a2 a3 …. an-1 an
0 1 2 3 n-1
Insertion Algorithms
Insert ( L, x, i)
If (i <= 0) or (i > length) then
return “Invalid List position”
// make room for the new item by shifting
// all items at position >= i
for j length to i increment –1 do
L[j+1] L[j]
// insert new item
L[i] = x
length length + 1
Implementing Operations (4)
2. Deletion Operations
• Deleting the first element requires shifting all the elements in the list up one
Delete (List L, integer i)
If (i <= 0) or (i > length) then
return “Invalid List position”
//delete item by shifting all items at
// positions > i toward the head of the list
for j i+1 to length do
L[j-1] L[j]
length length - 1
Implementing Operations (1)
3. Retrieve operation
• Retrieval of the i-th element can be implemented in efficiently since each
element can be accessed directly given its position.
Retrieve (List L, integer i)
If (i <= 0) or (i > length) then
return “Invalid List position”
elem List[i-1] // retrieve the
element
return elem
Implementing Operations (2)
4. Search Operation
• To find an element k in the list, you compare it with each element of the array
Search (List L, key k)
for i 1 to length do
elem Retrieve(L,i)
if k = elem then
return i //search
successful
return -1 // search unsuccessful
Advantages and Disadvantages
Advantages of the array-based implementation
•Simple to implement
•Implementing the list operations is very efficient
Disadvantages
•The array structure is static, placing a limitation on the size (specified
at compile time). This
• Can lead to overflow
• Is an inefficient use of space
C Implementation Of Array-
based List
• Lab 1
Linked Implementation
• A linked list consists of a sequence of basic structures (called
nodes). Each node contains two fields
• Data: which holds the elements of the list
• Next: which stores a pointer (link) to the next node in the
list
next
data
Linked List Implementation (2)
• Access to the list is gained through a pointer to the head of the list
(or a header node).
• This structure is called a singly linked list because each node in the
list is connected to the next by a single link.
head
cat rat bat
dog
Node Declaration
• In c++ the node can be declared as:
Class Node
{
Private:
T data;
Node<T<*next;
};
Linked List Declaration
• The list can be declared as
Class SLList{
Private:
Int Lenth;Node * head;//pointer to head
Public:
/specify the list operations
};
List Operations
• Unlike the array-based implementation,
there is no direct access to arbitrary
elements of the list.
• In order to access the i-th element, we must
traverse the list, beginning from the head until
the element is located.
Linked List Traversal
1. To find the address of the i-th element, we can use the following
algorithm
Traverse (integer i)
prev head //pointer to head
current head //make head the
current
if i ≠ 1 then
current current->next
for j 2 to i do
prev current
current current->next
return prev
2. Insertion Operation
• To insert an element at the position i, we need to
have access to position i-1, then splice the new
node into the list
ii +1
+2
i-1 i i+1
i
Insertion Algorithm
• Inserting after a node
• Suppose that we have a pointer, prev pointing to the node at position i-1
then insert operation can be performed using the following statements
Insert (Node ↑prev, x)
newNode new Node(x)
newNode->next prev -
>next
prev->next newNode
length length + 1
Exercise
• Write an algorithm for inserting an element
i) at the head of the list
ii) at the tail of the list
2. Deletion Operation
• To delete a data stored in a node at position i, the operation requires
that we modify the next field of the node at position i-1
i +1
i
i-1 i
Deletion Algorithm
• To delete a node
• We require two pointers, previous that points to the node at position i-1 and
current that points to the i-th node
• The operation can then be accomplished by
Delete (Node ↑previous, Node ↑current
previous->next current->next
delete current
length length + 1
Exercise
• Write an algorithm for delete an element
i) at the head of the list
ii) at the tail of the list
Advantages and Disadvantages
• Advantages of the Linked List
Implementation
• Memory is efficiently used, since there is no wasted space
• It is a very flexible data structure and can be used in many
applications, either by itself or as part of a more complicated data
structure
• Disadvantages
• Random access is not possible because to get to a particular node,
we must traverse the list starting from the head.
• Movement along the list is one way.
C Implementation of Linked List
• Lab 2
Other Variations of the Linked List
A singly linked list is time consuming if we want to
move to the end of the list, and/or
move in the reverse direction
The LIST ADT can also be implemented using a
doubly linked list
Circular linked list (singly or doubly)
Doubly Linked List
• In a doubly linked list, each node contains three
fields,
• Data: which holds the elements of the list
• Next: which stores a pointer (link) to the next node
in the list
• Previous: which stores a pointer (link) to the
previous node in the list
data
Doubly Linked List
L
a3
* a1 a2 a4 *
Circular Doubly Linked List
L
a3
a1 a2 a4