You are on page 1of 83

LISTS

Array list, singularly linked list


doubly linked list, circular list
M2/UNIT2.1
Lists
• A list is an ordered collection of elements
supporting random access to each element,
• Much like an array you can query a list to get the
value contained at any arbitrary element,
• All elements of a list must have the same type.
• Lists also preserve insertion order so that,
assuming there are no intervening modifications,
a given list will always return the same value for
the same position.
LISTS
• Like arrays, lists make no attempt to
preserve the uniqueness of values,
meaning a list may contain duplicate
values.
• The major difference between arrays and
lists, however, is that whereas an array is
fixed in size, lists can resize growing and
shrinking as necessary.
Lists
• It is usually possible to entirely replace
your use of arrays with lists in all but the
most memory-sensitive/time-critical
applications.
LISTS
everyday example
Lists
Index 0 Index 1
A C

Index 0 Index 1 Index 2


A B C

C has shifted one position to the right to make way for B the list has grown
automatically by 1
List Types
• Many ways to implement a list two most
common are :
– Array List
– Linked List
List Types
• An array list is sequence that supports
access to its elements by their indices
• As the name suggests, an array list uses
an array to hold the values. The array list
uses an array based implementation

• A linked list, conversely, is a chain of


elements in which each item has a
reference (or link) to the next (and
optionally previous) element.
Arrays V ArrayList
• Arrays are of fixed size; whereas an
ArrayList implements the list data structure
and can dynamically grow.
• An ArrayList is more flexible since you
don't need to know the required size
initially.
Arrays V ArrayList
• Arrays can hold primitive types like int,
char
A K W Z

10 21 34 56

• ArrayLists can only hold objects.

CAT DOG RAT PIG


Arrays V ArrayList
• Arrays are not part of a class, therefore
they have no methods that you can use to
change them, you need to refer to each
element in the array and do whatever you
want with each. i.e. there is no
add/remove for an array.
Quick note
• For most data structures there are some
basic operations
• Adding, inserting,
• deleting, removing,
• get checksize
• checkifempty,

• Example people in a queue at bank,


students in a classroom etc.
Core Operations on a List
• insert 
– Inserts a value into a list at a specified position (0, 1,
2, . . .). The size of the list will increase by one.
Throws IndexOutOfBoundsException if the specified
position is outside the range (0 <= index <= size()).
• delete 
– Deletes the value at a specified position (0, 1, 2, . . .)
in a list and returns whatever value was contained
therein. The size of the list will decrease by one.
Throws IndexOutOfBoundsException if the specified
position is outside the range (0 <= index < size()).
Core Operations on a List
• get 
– Obtains the value at a specified position (0, 1,
2, . . .) in the list. Throws
IndexOutOfBoundsException if the specified
position is outside the range (0 <= index <
size()).
• size 
– Obtains the number of elements in the list.
Convenience Operations on a List

• set 
– Sets the value at a specified position (0, 1, 2,. . .) in the list.
Returns the value originally at the specified position. Throws
IndexOutOfBoundsException if the specified position is outside
the range (0 <= index < size()). (i.e. Update command)
• add 
– Adds a value to the end of the list. The size of the list will
increase by one.
• delete 
– Deletes the first occurrence of a specified value from a list. The
size of the list will decrease by one if the value is found. Returns
true if the value is found or false if the value doesn’t exist.
• contains 
– Determines whether a specified value is contained within a list.
Convenience Operations on a List
• indexOf 
– Obtains the position (0, 1, 2,. . .) of the first occurrence of a
specified value within a list. Returns -1 if the value is not found.
Equality is determined by calling the value’s equals method.
• isEmpty 
– Determines whether a list is empty or not. Returns true if the list
is empty (size() == 0); otherwise, returns false.
• iterator 
– Obtains an Iterator over all elements in a list.
• clear 
– Deletes all elements from a list. The size of the list is reset to 0.
What is a Class
• A class is a set of individual objects all of
the same kind and have same
characteristics/properties e.g. bicycle
• There may be thousands of other bicycles
in existence, all of the same make and
model.
• Each bicycle was built from the same set
of blueprints and therefore contains the
same components.
What is a Class
• In object-oriented terms, we say that your
bicycle is an instance of the class of
objects known as bicycles.
• A class is the blueprint from which
individual objects are created.
What is an Interface
• Objects define their interaction with the outside
world through the methods that they expose.
• Methods form the object's interface with the
outside world;
• E.g. The buttons on the front of your television
set, for example, are the interface between you
and the electrical wiring on the other side of its
plastic casing.
What is an Interface
• You press the "power" button to turn the
television on and off.
• An interface is a group of related methods
with empty bodies.
• A bicycle's behaviour, if specified as an
interface, might appear as follows:
Interface
interface Bicycle {
// wheel revolutions per minute
void changeCadence(int newValue);
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
Java Tutorials
• To implement this interface, the name of
your class would change (to a particular
brand of bicycle, for example, such as
ACMEBicycle), and you'd use the
implements keyword in the class
declaration:
• class ACMEBicycle implements Bicycle
{ // remainder of this class // implemented
as before }
List Interface
package com.wrox.algorithms.lists;
import com.wrox.algorithms.iteration.Iterable;
public interface List extends Iterable {
public void insert(int index, Object value) throws IndexOutOfBoundsException;
public void add(Object value);
public Object delete(int index) throws IndexOutOfBoundsException;
public boolean delete(Object value);
public void clear();
public Object set(int index, Object value throws IndexOutOfBoundsException;
public Object get(int index) throws IndexOutOfBoundsException;
public int indexOf(Object value);
public boolean contains(Object value);
public int size();
public boolean isEmpty();
}

• Iterable interface contains one method


iterator
The iterator method
• The iterator method makes the list very flexible for
instance,
• If you were to create an array with three values and
iterate over each item printing out each in return the
code would be something like this

String[] anArray = ...;


anArray[0] = “Apple”;
anArray[1] = “Banana”;
anArray[2] = “Cherry”;
for (int i = 0; i < anArray.length; ++i) {
System.out.println(anArray[i]);
}
The Iterator method
• If you where to implement this using a list structure and
the iterator method then the code is as follows

List aList = ...;


aList.add(“Apple”);
aList.add(“Banana”);
aList.add(“Cherry”);
Iterator i = aList.iterator()
for (i.first(); !i.isDone(); i.next()) {
System.out.println(aList.current());
}
• There isn’t a lot of difference between the two you could
argue that in some ways, the version with the list is more
readable.
ArrayList
• Array list is dynamic. Just initialize arraylist and then add object or primitive
data type using add method.
• String[] empNames = new String[2];
• empNames[0] = "joe";
• empNames[1] = "ram";
• for (int i = 0; i < empNames.length; i++) {
• System.out.println("Name:"+empNames[i]);
• }
• ArrayList<String> list = new ArrayList<String>();
• list.add("joe");
• list.add("ram");
• for (int i = 0; i < list.size(); i++) {
• System.out.println("Name:"+list.get(i));
• }
ArrayList
• ArrayList is a class that is an
implementation of the List interface. It
contains many methods that allow you to
add/remove/compare its elements much
easier than with an Array. To add an
element, you can simply use the add()
method, e.g. list.add(Object),
The remove method can be used similarly.
ArrayList
• As the name suggests, an Array list uses
an array as the underlying mechanism for
storing elements, because of this, the fact
that you can index directly into arrays
makes implementing access to elements
almost trivial.
• An Array list is the fastest implementation
for indexed and sequential access.
• An ArrayList is, therefore, an
implementation of a list backed by an
array (re-sizeable)
ArrayList
ArrayList - Insertion
Array List
Insertion
• Note that we use a loop to move references out of the
way. The number of times we perform this loop depends
on the number of references we have to move to make
room for a reference to the new game entry. If there are
0, 1, or even just a few references to move over, this add
method will be pretty fast, but if there are a lot to move,
then this method could be fairly slow.

• Adding a reference to a new GameEntry object to the


entries array. The reference can now be inserted at index
2, since we have shifted all references to GameEntry
objects with scores less than the new one to the right.
Array List
Insertion
Array List
Removal
Array List
Removal
• Java code for performing the remove operation.
Array List
Removal
• Some Subtle Points About Entry Removal

• The entry ‘e’ to be removed at index I, we must first save e in a


temporary variable, we will use this variable to return e when we are
done removing it
• The second subtle point is that, in moving references higher than i
one cell to the left, we don't go all the way to the end of the array—
we stop at the second to last reference. We stop just before the end,
• because the last reference does not have any reference to its right
(hence, there is no reference to move into the last place in the
entries array). For the last reference in the entries array, it is enough
that we simply null it out.
• We conclude by returning a reference to the removed entry (which
no longer has any reference pointing to it in the entries array).
Array LIST
Applications
• One of the primary applications of arrays is the representation of strings
of characters. That is, string objects are usually stored internally as an
array of characters.
• Even if strings may be represented in some other way, there is a natural
relationship between strings and character arrays both use indices to refer
to their characters.
• Because of this relationship, Java makes it easy for us to create string
objects from character arrays and vice versa.

• One area where being able to switch from string to character array and back
again is useful is in cryptography, the science of secret messages and
their applications.
• This field studies ways of performing encryption, which takes a message,
called the plaintext, and converts it into a scrambled message, called the
ciphertext. Likewise, cryptography also studies corresponding ways of
performing decryption, which takes a ciphertext and turns it back into its
original plaintext.
Arrays V Array List
Downsides to using an Array
1. The is that each time you insert a new element, you need to shift
any elements in higher positions one place to the right by
physically copying them.
• Similarly, when deleting an existing element, you need to shift any
objects in higher positions one place to the left to fill the gap left by
the deleted element.

2. Because arrays are fixed in size, anytime you need to increase the
size of the list, you also need to reallocate a new array and copy
the contents over. This clearly affects the performance of insertion
and deletion.

• However, an array list is a good starting point when first moving


away from simple arrays to using richer data structures such as
lists.
Linked List

• Arrays are nice and simple for storing


things in a certain order, but they have the
drawback of not being very adaptable,
since we have to fix the size N of the array
in advance. There are other ways to store
a sequence of elements, however, that do
not have this drawback
Linked List
• An alternate implementation of an array is a linked list.
• A linked list, in its simplest form, is a collection of
nodes that together form a linear ordering.
• Rather than use an array to hold the elements, a linked
list contains individual elements with links between them.
• With an array list, when deleting or inserting, some
portion of the underlying array needs to be copied. With
a linked list, however, each time you wish to insert or
delete an element, you need only update the references
to and from the next and previous elements,
respectively.
• This makes the cost of the actual insertion or deletion
almost negligible in all but the most extreme cases. For
lists with extremely large numbers of elements, the
traversal time can be a performance issue.
Linked List
Post office box analogy
• I have a book I want to keep out of the house for safe keeping so decided on
purchasing a post office box, but it is too thick to fit in a single post office box, so
instead I divide the book into two halves and purchases two post office boxes.
• In the first box, I put the first half of the book and a key to the second box, and in
the second box I put the second half of the book. I hold the key to the first box. No
matter how large the book is, this scheme can be extended to any number of
boxes by always putting the key to the next box in the previous box.
• In this analogy, the boxes correspond to elements or nodes, the keys correspond
to pointers, and the book itself is the data. The key given to Me is the head
pointer, while those stored in the boxes are next pointers. The scheme as
described above is a singly linked list
Singly Linked List
• It might seem strange to have a node reference
another node, but such a scheme easily works.
• The next reference inside a node can be viewed as a
link or pointer to another node.
• Likewise, moving from one node to another by
following a next reference is known as link hopping
or pointer hopping.
• The first and last node of a linked list usually are
called the head and tail of the list, respectively.
Thus, we can link hop through the list starting at the
head and ending at the tail.
• We can identify the tail as the node having a null
next reference, which indicates the end of the list.
• A linked list defined in this way is known as a singly
linked list.
Singly Linked List

• A linked list, in its simplest form, is a


collection of nodes that together form a
linear ordering
Singly Linked List

• Like an array a singly linked list keeps its


elements in a certain order. This order is
determined by the chain of next links going from
each node to its successor in the list.
• Unlike an array, a singly linked list does not have
a predetermined fixed size, and uses space
proportional to the number of its elements.
• Likewise, we do not keep track of any index
numbers for the nodes in a linked list. So we
cannot tell just by examining a node if it is the
second, fifth, or twentieth node in the list.
Singly Linked List

• When using a singly linked list, we can


easily insert an element at the head of the
list. The main idea is that we
– create a new node
– set its next link to refer to the same
object as head,
– and then set head to point to the
new node.
singly linked list
Inserting at head
singly linked list
Inserting at head
Inserting a new node v at the beginning of a singly linked list. Note
that this method works even if the list is empty.
set the next pointer for the new node v
Make variable head point to v.
Singly linked list
Inserting at tail
• Inserting an Element at the Tail of a Singly
Linked List
• Insert can also be done at the tail node by
– create a new node,
– assign its next reference to point to the null
object,
– set the next reference of the tail to point to
this new object,
– and then assign the tail
singly linked list
Inserting at tail
singly linked list
Inserting at tail
singly linked list
deleting at head
singly linked list
deleting at head
singly linked list
deleting at tail
• Deleting the tail node of a singly linked list is not
easy.
• Even if we have a tail reference directly to the
last node of the list, we must be able to access
the node before the last node in order to remove
the last node.
• But we cannot reach the node before the tail by
following next links from the tail. The only way to
access this node is to start from the head of the
list and search all the way through the list. But
such a sequence of link hopping operations
could take a long time.
Doubly Linked Lists

• Removing an element at the tail of a singly


linked list is not easy. Indeed, it is time
consuming to remove any node other than the
head in a singly linked list, since we do not have
a quick way of accessing the node in front of the
one we want to remove.

• Indeed, there are many applications where we


do not have quick access to such a predecessor
node. For such applications, it would be nice to
have a way of going both directions in a linked
list.
Doubly Linked Lists

• There is a type of linked list that


allows us to go in both directions—
forward and reverse in a linked list. It
is the doubly linked list. Such lists
allow for a great variety of quick
update operations, including insertion
and removal at both ends, and in the
middle.
Doubly Linked Lists

• A node in a doubly linked list stores two


references a next link which points to the
next node in the list, and a prev link, which
points to the previous node in the list.
• To summarize, a doubly linked list nodes
contain three fields:
– A value,
– A link to the next node,
– a link to the previous node.
Doubly Linked Lists
Header and Trailer Sentinels
• To simplify programming, it is convenient to add special
nodes at both ends of a doubly linked list:
– a header node just before the head of the list,
– and a trailer node just after the tail of the list.
• These "dummy" or sentinel nodes do not store any
elements. The header has a valid next reference but a
null prev reference, while the trailer has a valid prev
reference but a null next reference.
• A doubly linked list with these sentinels is shown in the
next slide note that a linked list object would simply need
to store references to these two sentinels and a size
counter that keeps track of the number of elements (not
counting sentinels) in the list.
Doubly Linked Lists
Header and Trailer Sentinels
• A doubly linked list with sentinels, header
and trailer, marking the ends of the list. An
empty list would have these sentinels
pointing to each other. We do not show the
null prev pointer for the header nor do we
show the null next pointer for the trailer.
Doubly Linked Lists adding at
head
Doubly Linked Lists
middle insertion
• Doubly linked list are convenient for maintaining a list of
elements while allowing for insertion and removal in the
middle of the list.
• Given a node v of a doubly linked list (which could be
possibly the header but not the trailer), ?? we can easily
insert a new node z immediately after v. Specifically, let
w the be node following v. We execute the following
steps:
– 1. make z's prev link refer to v
– 2. make z's next link refer to w
– 3. make w's prev link refer to z
– 4. make v's next link refer to z
Doubly Linked Lists
middle insertion
• Inserting a new node z after a given node
v in a doubly linked list.
Doubly Linked Lists
middle insertion
• Adding a new node after the node storing
JFK: (a) creating a new node with element
BWI and linking it in; (b) after the insertion.
Doubly Linked Lists
middle delete
• Removing a node v in a doubly linked list.
This method works even if v is the first,
last, or only nonsentinel node.
Doubly Linked Lists
middle delete (node PVD)
• (a) before the removal; (b) linking out the
old node; (c) after the removal (and
garbage collection).
Circularly Linked Lists

• A circularly linked list has the same kind of


nodes as a singly linked list.

• Each node in a circularly linked list has a next


pointer and a reference to an element.

• There is no head or tail in a circularly linked list.


For instead of having the last node's next pointer
be null, in a circularly linked list, it points back to
the first node. Thus, there is no first or last node.
Circularly Linked Lists

• In linear linked lists if a list is traversed (all the


elements visited) an external pointer to the list
must be preserved in order to be able to
reference the list again.
• Circular linked lists can be used to help the
traverse the same list again and again if needed.

• A circular list is very similar to the linear list


where in the circular list the pointer of the last
node points not NULL but the first node.
Circularly Linked Lists
• If we traverse the nodes of a circularly linked list from
any node by following next pointers, we will cycle
through the nodes.

• Even though a circularly linked list has no beginning or


end, we nevertheless need some node to be marked as
a special node, which we call the cursor.

• The cursor node allows us to have a place to start from if


we ever need to traverse a circularly linked list. And if we
remember this starting point, then we can also know
when we are done-we are done with a traversal of a
circularly linked list when we return to the node that was
the cursor node when we started.
Circularly Linked Lists:
Some basic operations
• We can then define some simple update
methods for a circularly linked list:
• add(v): Insert a new node v immediately after
the cursor;
– if the list is empty, then v becomes the cursor and its
next pointer points to itself.
• remove(): Remove and return the node v
immediately after the cursor (not the cursor
itself, unless it is the only node);
– if the list becomes empty, the cursor is set to null.
Circularly Linked Lists
Applications
• Round Robin Time-Sharing jobs of Operating System,
i.e. simple multi tasking by PC
• In a time sharing problem solved by the operating
system. In a timesharing environment the operating
system must have a list of present users and must
alternatively allow each user to use a small amount of
CPU time and then move on to the next user etc.
• For this application there should be no NULL pointer
unless there is absolutely no one requesting CPU time.
Usually you would find that during this slot the operating
system would start perform some housekeeping
routines.
Linked List
Pros & Cons
• Linked lists are not really a good general-purpose
data structure because they do not allow any form of
efficient indexing. This invariably requires scanning
most of or all of the list of elements. Many basic
operations are affected by this such as
– Obtaining the last node of the list (assuming that the last
node is not maintained as a separate node reference in the
list structure)
– Finding a node that contains a given datum (finding by
VALUE)
– Locating where a new node should be inserted

• Linked list are usually only used for algorithms that


iterate over the list anyway and insert or remove
nodes while they do it
Linked List V Array List (dynamic arrays)
Advantages of Linked list over Array list (dynamic arrays)
• Most of the Insertion or deletion of element(s) are constant-
time operations (i.e. at a specific point of a list, assuming
that we have a pointer to the node (before the one to be
removed, or before the insertion point)
• Insertion in a Array List at random locations will require
moving half of the elements on average, and all the
elements in the worst case (i.e copying and resizing).
• Deletion in a Array List can be constant time by somehow
marking the slot as “vacant” avoiding moving elements in
the array but the downside of this causes fragmentation
that impedes the performance of iteration
Linked List V Array List (dynamic arrays)
Advantages of Array list over Linked List
• Array List (as well as fixed-size array data structures)
allow O(1) constant-time random access
• Linked lists allow only sequential access (finding a
specific element in a linked list, even if it is sorted,
normally requires O(n) time linear search ) to elements
making linked lists unsuitable for applications where a
quick look-up of an element by its index is required.
• Where sequential access is required for a particular
operation regardless, sequential access on arrays and
Array List is faster than linked lists on many machines,
because they have optimal locality of reference and thus
make good use of data caching
Linked List vs Array List (dynamic arrays)

Advantages of Array list over Linked List, contd.


• The difference between the linked list and array list
implementations of indexOf() is really only in how you
navigate from one element to the next.
• With an array list it’s easy: You simply increment an
index and access the array directly.
• With linked lists, on the other hand, you need to use
the links themselves to move from one element to the
next. If the value is found, its position is returned.
Reference Java
Tutorials/Interfaces
• Where you have different pieces of
code/software written by different people it
is important for the different programmers
to agree to a "contract" that spells out how
their software interacts.
Reference Java Tutorials
• Each group should be able to write their
code without any knowledge of how the
other group's code is written
• Generally speaking, interfaces are such
contracts.
• An interface can be used as an industry
standard Application Programming
Interface (API). APIs are also common in
commercial software products.
LN2.1.2
Patients’ allocation of beds in a hospital
start
5 Bed nos. patient. next.
1 kirk. 7
2. .
3 dean .11
4. maxwell. .12
5. adams. 3
6. . .
7 lane. .4
8 green 1
9. samuels. .0
10 .
11. fields 8
12 nelson 9

5 3 11
Representation of Linked List in
memory
• The patients in a hospital ward example
shows nodes in a list do not have to
occupy adjacent elements in an array
Representation of Linked List in
memory (example)
• Let LIST be a linked list
• LIST requires two linear arrays INFO and
LINK. Then INFO[K] and LINK[K] contain
the information part and the nextpointer
part of a node K of list. The variable name
of LIST is START which contains the
location of the beginning of the LIST
Representation of Linked List in
memory (example)
• The next diagram shows a representation of
a linked list in memory where each node of
the list contains a single character .
• In other words the list represents a string
• START = 9 so INFO[9] = N 1st character
• LINK[9] = 3 so INFO[3] = 0 2nd character
• LINK[3] =6 so INFO[6] = blank 3rd character
• ………… NO EXIT
Representation of Linked List in
memory (example)
9 INFO. LINK.
1
2 .
3 O 6
4 T 0
5 .
6 . .11
7 X .10
8
9 N .3
10 .I 4
11 E 7
12
Representation of two lists of test scores: ALG and GEOM
TEST. LINK.
1
2 74. 14 Node 2 of ALG
ALG 11
3
4 82 0 Node 4 of ALG
5 .84 12 Node 1 of GEOM
6 .78 .0 .
7 74 8. .Node 3 of GEOM
GEOM 5 8
9 .
10 .
11 88 2 Node 1 of ALG
12 62 7 Node 2 of GEOM
13 74 6
14 93 4 Node 3 of ALG

ALG: 88, 74, 93, 82


GEOM: 84, 62, 74
Go through the following in LN-2.1.2:
• Example 5.4 • Example 5.18
• Example 5.5 • Page 5.32:
• Example 5.10 properties of circular
• Example 5.13 header lists
• Example 5.15 • Page 5.35:
• Example 5.16 Polynomials
• Example 5.20
• Example 5.17
• 5.9 page 3.31:
header linked list
Read
• Memory Allocation
• Garbage Collection
• Header Linked List
– grounded header
– Circular header list
• Overflow
• Underflow
Read
• Header Linked List always contains a
special node called the header node at the
start of the list (header node could store
special information about the entire file)
– grounded header list (the last node contains
the null pointer
– Circular header list (the last node points back
to the header node)
• Header linked list are used frequently to
maintain polynomials in memory

You might also like