You are on page 1of 8

CS301 Data Structures

Lecture No.
02
___________________________________________________________________

Data Structures
Lecture No. 02
Reading Material
Data Structures and Algorithm Analysis in C++

Chapter. 3
3.1, 3.2, 3.2.1, 3.2.2

Summary
1)

List Implementation
add Method
next Method
remove Method
find Method
Other Methods
Analysis Of Array List
List Using Linked Memory
Linked List

2)
3)
4)

Today, we will discuss the concept of list operations. You may have a fair idea of
start operation that sets the current pointer to the first element of the list while the tail
operation moves the current pointer to the last element of the list. In the previous
lecture, we discussed the operation next that moves the current pointer one element
forward. Similarly, there is the back operation which moves the current pointer one
element backward.

List Implementation
Now we will see what the implementation of the list is and how one can create a list in
C++. After designing the interface for the list, it is advisable to know how to
implement that interface. Suppose we want to create a list of integers. For this
purpose, the methods of the list can be implemented with the use of an array inside.
For example, the list of integers (2, 6, 8, 7, 1) can be represented in the following
manner where the current position is 3.
A

current

size

In this case, we start the index of the array from 1 just for simplification against the
usual practice in which the index of an array starts from zero in C++. It is not
necessary to always start the indexing from zero. Sometimes, it is required to start the
indexing from 1. For this, we leave the zeroth position and start using the array from
index 1 that is actually the second position. Suppose we have to store the numbers
from 1 to 6 in the array. We take an array of 7 elements and put the numbers from the
index 1. Thus there is a correspondence between index and the numbers stored in it.
This is not very useful. So, it does not justify the non-use of zeroth position of the

Page 1 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
array out-rightly. However for simplification purposes, it is good to use the index from
1.
add Method
Now we will talk about adding an element to the list. Suppose there is a call to add an
element in the list i.e. add(9). As we said earlier that the current position is 3, so by
adding the element 9 to the list, the new list will be (2, 6, 8, 9, 7, 1).
To add the new element (9) to the list at the current position, at first, we have to make
space for this element. For this purpose, we shift every element on the right of 8 (the
current position) to one place on the right. Thus after creating the space for new
element at position 4, the array can be represented as
A

7
4

current

size

Now in the second step, we put the element 9 at the empty space i.e. position 4. Thus
the array will attain the following shape. The figure shows the elements in the array in
the same order as stored in the list.
A

current

size

We have moved the current position to 4 while increasing the size to 6. The size shows
that the elements in the list. Where as the size of the array is different that we have
defined already to a fixed length, which may be 100, 200 or even greater.
next Method
Now lets see another method, called next. We have talked that the next method
moves the current position one position forward. In this method, we do not add a new
element to the list but simply move the pointer one element ahead. This method is
required while employing the list in our program and manipulating it according to the
requirement. There is also an array to store the list in it. We also have two variablescurrent and size to store the position of current pointer and the number of elements in
the list. By looking on the values of these variables, we can find the state of the list i.e.
how many elements are in the list and at what position the current pointer is.
The method next is used to know about the boundary conditions of the list i.e. the
array being used by us to implement the list. To understand the boundary conditions,
we can take the example of an array of size 100 to implement the list. Here, 100
elements are added to the array. Lets see what happens when we want to add 101 st
element to the array? We used to move the current position by next method and
reached the 100th position. Now, in case of moving the pointer to the next position (i.e.
101st), there will be an error as the size of the array is 100, having no position after this
point. Similarly if we move the pointer backward and reach at the first position
regardless that the index is 0 or 1. But what will happen if we want to move backward
from the first position? These situations are known as boundary conditions and need
attention during the process of writing programs when we write the code to use the
list. We will take care of these things while implementing the list in C++ programs.
remove Method
We have seen that the add method adds an element in the list. Now we are going to
Page 2 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
discuss the remove method. The remove method removes the element residing at the
current position. The removal of the element will be carried out as follows. Suppose
there are 6 elements (2, 6, 8, 9, 7, 1) in the list. The current pointer is pointing to the
position 5 that has the value 7. We remove the element, making the current position
empty. The size of the list will become 5. This is represented in the following figure.

current

size

6
5

We fill in the blank position left by the removal of 7 by shifting the values on the right
of position 5 to the left by one space. This means that we shift the remaining elements
on the right hand side of the current position one place to the left so that the element
next to the removed element (i.e. 1) takes its place (the fifth position) and becomes the
current position element. We do not change the current pointer that is still pointing to
the position 5. Thus the current pointer remains pointing to the position 5 despite the
fact that there is now element 1 at this place instead of 7. Thus in the remove method,
when we remove an element, the element next to it on the right hand side comes at its
place and the remaining are also shifted one place to the right. This step is represented
by the following figure.

current

size

find Method
Now lets talk about a function, used to find a specific element in the array. The find (x)
function is used to find a specific element in the array. We pass the element, which is to
be found, as an argument to the find function. This function then traverses the array
until the specific element is found. If the element is found, this function sets the current
position to it and returns 1 i.e. true. On the other hand, if the element is not found, the
function returns 0 i.e. false. This indicates that the element was not found. Following is
the code of this find(x) function in C++.
int find (int x)
{
int j ;
for (j = 1; j < size + 1; j++ )
if (A[j] == x )
break ;
if ( j < size + 1)
{
current = j ;
return 1 ;
}
return 0 ;
}

// x is found
//current points to the position where x found
// return true
//return false, x is not found

In the above code, we execute a for loop to traverse the array. The number of
Page 3 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
execution of this loop is equal to the size of the list. This for loop gets terminated when
the value of loop variable (j) increases from the size of the list. However we terminate
the loop with the break statement if the element is found at a position. When the
control comes out from the loop, we check the value of j. If the value of j is less than
the size of the array, it means that the loop was terminated by the break statement. We
use the break statement when we find the required element (x) in the list. The
execution of break statement shows that the required element was found at the
position equal to the value of j. So the program sets the current position to j and
comes out the function by returning 1 (i.e. true). If the value of j is greater than the
size of the array, it means that the whole array has traversed and the required element
is not found. So we simply return 0 (i.e. false) and come out of the function.
Other Methods
There are some other methods to implement the list using an array. These methods are
very simple, which perform their task just in one step (i.e. in one statement). There is a
get() method , used to get the element from the current position in the array. The
syntax of this function is of one line and is as under
return A[current] ;
This statement returns the element to which the current is pointing to (i.e. the current
position) in the list A.
Another function is update(x). This method is used to change (set) the value at the
current position. A value is passed to this method as an argument. It puts that value at
the current position. The following statement in this method carries out this process.
A [current] = x ;
Then there is a method length( ).This method returns the size of the list. The syntax of
this method is
return size ;
You may notice here that we are returning the size of the list and not the size of the
array being used internally to implement the list. This size is the number of the elements
of the list, stored in the array.
The back() method decreases the value of variable current by 1. In other words, it
moves the current position one element backward. This is done by writing the
statement.
current -- ;
The -- is a decrement operator in C++ that decreases the value of the operand by one.
The above statement can also be written as
current = current -1 ;
The start() method sets the current position to the first element of the list. We know
that the index of the array starts from 0 but we use the index 1 for the starting position.
We do not use the index zero. So we set the current position to the first element by
writing

Page 4 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
current = 1 ;
Similarly, the end() method sets the current position to the last element of the list i.e.
size. So we write
current = size ;

Analysis of Array List


Now we analyze the implementation of the list while using an array internally. We
analyze different methods used for the implementation of the list. We try to see the
level upto which these are efficient in terms of CPUs time consumption. Time is the
major factor to see the efficiency of a program.
Add
First of all, we have talked about the add method. When we add an element to the list,
every element is moved to the right of the current position to make space for the new
element. So, if the current position is the start of the list and we want to add an
element in the beginning, we have to shift all the elements of the list to the right one
place. This is the worst case of adding an element to the list. Suppose if the size of the
list is 10000 or 20000, we have to do the shift operation for all of these 10000 or
20000 elements. Normally, it is done by shifting of elements with the use of a for loop.
This operation takes much time of the CPU and thus it is not a good practice to add an
element at the beginning of a list. On the other hand, if we add an element at the end of
the list, it can be done by carrying out no shift operation. It is the best case of adding
an element to the list. However, normally we may have to move half of the elements.
The usage of add method is the matter warranting special care at the time of
implementation of the list in our program. To provide the interface of the list, we just
define these methods.
Remove
When we remove an element at the current position in the list, its space gets empty.
The current pointer remains at the same position. To fill this space, we shift the
elements on the right of this empty space one place to the left. If we remove an
element from the beginning of the list, then we have to shift the entire remaining
elements one place to the left. Suppose there is a large number of elements, say 10000
or 20000, in the list. We remove the first element from the list. Now to fill this space,
the remaining elements are shifted (that is a large number). Shifting such a large
number of elements is time consuming process. The CPU takes time to execute the for
loop that performs this shift operation. Thus to remove an element at the beginning of
the list is the worst case of remove method. However it is very easy to remove an
element at the end of the list. In average cases of the remove method we expect to shift
half of the elements. This average does not mean that in most of the cases, you will
have to shift half the elements. It is just the average. We may have to shift all the
elements in one operation (if we remove at the beginning) and in the second operation,
we have to shift no element (if we remove at the end). Similarly, in certain operations,
we have to shift just 10, 15 elements.
Find
We have discussed that the find method takes an element and traverses the list to find
that element. The worst case of the find method is that it has to search the entire list
from beginning to end. So, it finds the element at the end of the array or the element is
Page 5 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
not found. On average the find method searches at most half the list.
The other methods get (), length () etc are one-step methods. They carry out their
operation in one instruction. There is no need of any loop or other programming
structures to perform the task. The get() method gets the value from the specified
position just in one step. Similarly the update() method sets a value at the specific
position just in one-step. The length () method returns the value of the size of the list.
The other methods back(), start() and end() also perform their tasks only in one step.

List using Linked Memory


We have seen the implementation of the list with the use of an array. Now we will
discuss the implementation of the list while using linked memory. In an array, the
memory cells of the array are linked with each other. It means that the memory of the
array is contiguous. In an array, it is impossible that one element of the array is located
at a memory location while the other element is located somewhere far from it in the
memory. It is located in very next location in the memory. It is a property of the array
that its elements are placed together with one another in the memory. Moreover, when
we have declared the size of the array, it is not possible to increase or decrease it
during the execution of the program. If we need more elements to store in the array,
there is need of changing its size in the declaration. We have to compile the program
again before executing it. Now array will be of the new size. But what happens if we
again need to store more elements? We will change the code of our program to change
the declaration of the array while recompiling it.
Suppose we have used the dynamic memory allocation and created an array of 100
elements with the use of new operator. In case of need of 200 elements, we will release
this array and allocate a new array of 200 elements. Before releasing the previous
array, it will wise to copy its elements to the new array so that it does not lose any
information. Now this new array is in ready for use position. Thus the procedure of
creating a new array is not an easy task.
To avoid such problems, usually faced by the programmers while using an array, there
is need of using linked memory in which the various cells of memory, are not located
continuously. In this process, each cell of the memory not only contains the value of
the element but also the information where the next element of the list is residing in the
memory. It is not necessary that the next element is at the next location in the memory.
It may be anywhere in the memory. We have to keep a track of it. Thus, in this way, the
first element must explicitly have the information about the location of the second
element. Similarly, the second element must know where the third element is located
and the third should know the position of the fourth element and so on. Thus, each cell
(space) of the list will provide the value of the element along with the information
about where the next element is in the memory. This information of the next element is
accomplished by holding the memory address of the next element. The memory
address can be understood as the index of the array. As in case of an array, we can
access an element in the array by its index. Similarly, we can access a memory location
by using its address, normally called memory address.

Linked List
For the utilization of the concept of linked memory, we usually define a structure,
called linked list. To form a linked list, at first, we define a node. A node comprises two
fields. i.e. the object field that holds the actual list element and the next that holds the
starting location of the next node.

Page 6 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________
object

next

A chain of these nodes forms a linked list. Now lets consider our previous list, used
with an array i.e. 2, 6, 8, 7, 1. Following is the figure which represents the list stored as
a linked list.
Head
2

size = 5

current
This diagram just represents the linked list. In the memory, different nodes may occur
at different locations but the next part of each node contains the address of the next
node. Thus it forms a chain of nodes which we call a linked list.
While using an array we knew that the array started from index 1that means the first
element of the list is at index 1. Similarly in the linked list we need to know the starting
point of the list. For this purpose, we have a pointer head that points to the first node
of the list. If we dont use head, it will not be possible to know the starting position of
the list. We also have a pointer current to point to the current node of the list. We need
this pointer to add or remove current node from the list. Here in the linked list, the
current is a pointer and not an index as we used while using an array. The next field of
the last node points to nothing .It is the end of the list. We place the memory address
NULL in the last node. NULL is an invalid address and is inaccessible.
Now again consider the list 2, 6, 8, 7, 1. The previous figure represents this list as a
linked list. In this linked list, the head points to 2, 2 points to 6, 6 points to 8, 8 points
to 7 and 7 points to 1. Moreover we have the current position at element 8.
This linked list is stored in the memory. The following diagram depicts the process
through which this linked list is stored in the memory.

Page 7 of 8

CS301 Data Structures


Lecture No.
02
___________________________________________________________________

current

head

1051

1052

1063

1053
1054

1055
1056

1051

1057
1058

7
1060

1059
1060

1061
1062

0
1054

1063
1064

8
1057

1065
We can see in the figure that each memory location has an address. Normally in
programming, we access the memory locations by some variable names. These variable
names are alias for these locations and are like labels that are put to these memory
locations. We use head and current variable names instead of using the memory
address in numbers for starting and the current nodes. In the figure, we see that head is
the name of the memory location 1062 and the name current is used for the memory
address 1053. The head holds the address 1054 and the element 2, the first one in the
list, is stored in the location 1054. Similarly current holds the address 1063 where the
element 8 is stored which is our current position in the list. In the diagram, two
memory locations comprise a node. So we see that the location 1054 holds the element
2 while the next location 1055 holds the address of the memory location (1051) where
the next element of the list (i.e. 6) is stored. Similarly the next part of the node that has
value 6 holds the memory address of the location occupied by the next element (i.e. 8)
of the list. The other nodes are structured in a similar fashion. Thus, by knowing the
address of the next element we can traverse the whole list.

Page 8 of 8

You might also like