ASSIGNMENT 2 FRONT SHEET
Qualification
BTEC Level 5 HND Diploma in Computing
Unit number and title
Unit 19: Data Structures and Algorithms
Submission date
12/03/2022
Date Received 1st submission
Re-submission Date
Date Received 2nd submission
Student Name
Student ID
Class
Assessor name
Quan-Hong Do
Student declaration
I certify that the assignment submission is entirely my own work and I fully understand the consequences of plagiarism. I understand that
making a false declaration is a form of malpractice.
Student’s signature
Grading grid
P4
P5
P6
P7
M4
M5
D3
D4
Page 1 of 35
Summative Feedback:
Grade:
Resubmission Feedback:
Assessor Signature:
Date:
Internal Verifier’s Comments:
IV Signature:
Page 2 of 35
Table of Contents
A.
INTRODUCTION ....................................................................................................................................... 5
B.
IMPLEMENT COMPLEX DATA STRUCTURES AND ALGORITHMS ......................................................... 6
1.
2.
3.
C.
Singly vs. Doubly Linked-List................................................................................................................ 6
1.1.
Highlight some differences between Singly and Doubly Linked-List ........................................... 6
1.2.
Describe Singly and Doubly Linked-List’s operations .................................................................. 7
1.3.
Implement Singly and Doubly Linked-List .................................................................................... 8
Insert An Element In The Middle Of A Linked-List ............................................................................ 16
2.1.
Implementation ......................................................................................................................... 16
2.2.
Explanation of the implementation ........................................................................................... 16
Sorting in Linked-List ......................................................................................................................... 18
3.1.
Describe your selected sorting algorithm . ................................................................................ 18
3.2.
Implementation ......................................................................................................................... 19
3.3.
Explanation Of The Implementation .......................................................................................... 19
IMPLEMENT ERROR HANDLING AND REPORT TEST RESULTS ........................................................... 22
1.
Testing Plan ....................................................................................................................................... 22
2.
Evaluation .......................................................................................................................................... 25
2.1.
Overall: ....................................................................................................................................... 25
2.2.
Explain and Solution ................................................................................................................... 25
D.
DISCUSS HOW ASYMPTOTIC ANALYSIS CAN BE USED TO ASSESS THE EFFECTIVENESS OF AN
ALGORITHM .................................................................................................................................................. 26
1.
Asymptotic Analysis:.......................................................................................................................... 26
2.
Asymptotic Notations And How They Relate To Ideas Of Best, Average And Worst Case: .............. 26
3.
Some Examples to Clarify O(1), O(n), O(N log N) .............................................................................. 28
E. DETERMINE TWO WAYS IN WHICH THE EFFICIENCY OF AN ALGORITHM CAN BE MEASURED,
ILLUSTRATING YOUR ANSWER WITH AN EXAMPLE ..................................................................................... 31
F.
TRADE-OFF WHEN SPECIFYING AN ADT................................................................................................ 33
G.
CONCLUSION ..................................................................................................................................... 34
References .................................................................................................................................................... 34
Page 3 of 35
List of Figures
Figure 1: Node structure of singly linked list .................................................................................................. 8
Figure 2: instance variables and constructor of linked list............................................................................. 9
Figure 3: addLast Operation and addFirst Operation of singly ...................................................................... 9
Figure 4: singly Insert operation ................................................................................................................... 10
Figure 5: Singly Search Operation: ............................................................................................................... 10
Figure 6:getFirst and getLast operation ....................................................................................................... 10
Figure 7: Size and isEmpty Operation of singly list ...................................................................................... 11
Figure 8: Singly RemoveFirst and RemoveLast Operation: .......................................................................... 11
Figure 9: Node class of doubly linked list ..................................................................................................... 12
Figure 10: Doubly linked list class................................................................................................................. 12
Figure 11: size and isEmpty operation of doubly ......................................................................................... 13
Figure 12: addFirst and addLast operations of doubly ................................................................................ 13
Figure 13: search operation of doubly ......................................................................................................... 14
Figure 14: Insert Doubly ............................................................................................................................... 14
Figure 15: GetFirst and Last doubly.............................................................................................................. 15
Figure 16: Remove First and Last Operation doubly .................................................................................... 15
Figure 17: InsertMiddle Doubly Linked List .................................................................................................. 16
Figure 18: Searching the previous node ....................................................................................................... 17
Figure 19: adjust pointer of new node ......................................................................................................... 18
Figure 20: Complete Inserting process......................................................................................................... 18
Figure 21: Sorting algorithm Implement ...................................................................................................... 19
Page 4 of 35
A. INTRODUCTION
In this assignment, there are some tasks I need to complete such as implementing a complex algorithm
and data structure(singly and doubly linked list) that consists the valid operations. Following that, I will
implement error handling and report test results. Additionally, I will discuss how asymptotic analysis
can be used to assess the effectiveness of an algorithm. To more specific, taking an example to clarify
some concepts of big-O notation. Determining two ways in which the efficiency of an algorithm can be
measured will be discussed and illustrating my answer with an example. In the end, discussing about
space-time trade-off when specifying an adt.
Page 5 of 35
B. IMPLEMENT COMPLEX DATA STRUCTURES AND ALGORITHMS
1. Singly vs. Doubly Linked-List
1.1. Highlight some differences between Singly and Doubly Linked-List
Basically, both singly and doubly linked list could be understood as the characteristic variation of
linked list. Using Singly or Doubly linked list based on the purpose to achieve and system limitations.
Singly linked list is commonly viewed as the simple implementation of linked list ADT and doubly
linked list is the more complex one. Moreover, most of the strengths of this one also are the
weakness of the other and vice versa. In other words, they are put in the opposite assessment. For
more specific, here are the comparison table of these two:
Singly Linked List
Doubly Linked List
Concept
Singly Linked list or the basic linked list Doubly linked list also stores data in a
which stores each data in a node and node but each node of the doubly
each node of singly linked list only has linked list has two pointers. One point
one pointer point to the next node.
to the previous node and one point to
the next node
Node structure
As said above, a node of this one only has A node of this one has two pointers
one pointer.
Structure:
Structure:
Node data
Node data
Next pointer(next node)
Next pointer(next node)
Previous pointer(previous node)
Order of
accessing
Each element of a singly linked list can The doubly linked list provides two-way
only be accessed or traversed in one way: access (both from head to tail and from
head-to-tail(or tail-to-head).
tail to both)
Memory usage
It uses quite less memory because the It uses memory as twice as singly
node of a singly linked list only stores one because its node store both the next
pointer.
pointer as well as the previous pointer
Performance
RemoveLast operation needs O(n)
Searching the known position: Best
caseO(1), average case: O(n),
worst
case O(n)
Easy at insertion
Cannot access the previous node
When the need of saving memory and
searching or insertion is not necessary,
the singly linked list is more suitable.
When to use
Based
implementation:
Stack
Binary tree
Hash table
RemoveLast operation needs O(1)
Searching the known position: Best
case (1), average case: O(1), worst case
O(n)
More actions in insertion
Easy to access the previous node
If we require greater efficiency when
searching or inserting and memory is
not an issue, we should use a doubly
linked list.
Stack
Queue
Page 6 of 35
1.2. Describe Singly and Doubly Linked-List’s operations
a) Singly Linked List operations
addFirst(): insert an element saved to the new node before the current head of the linked
list. The next pointer of the new node will point to the current head. The new head now is
set to the new node.
addLast(): insert an element saved to the new node after the current tail of the linked list.
The next pointer of the current tail will point to the new node. The new tail now is set to the
new node.
Insert(): traversal and find the previous index node and set the next pointer of this node to
the new node. The next pointer of the new node is set to the next pointer of the previous
node.
removeFirst(): set the head pointer to the next node of the current head and set the next
pointer of this one to null.
removeLast(): traversal sequentially to the previous node of the tail pointer node. Set the
next pointer of the previous node to null.
size(): return the size instance variable which is updated constantly whenever one change of
data in the linked list happens.
isEmpty(): if size is equal to 0, return true and vice versa.
getFirst(): return the first pointer if the linked list Is not null
getLast(): return the last pointer if the linked list Is not null
Search(): traversal by looping via each element to find the element at the correct index and
return this one.
Sort(): apply the merge sort algorithm to sort the list ascendingly.
b) Doubly Linked List operation
addFirst(): insert an element saved to the new node before the current head of the linked
list. The next pointer of the new node will point to the current head and the previous
pointer of the current head to the new node. The new head now is set to the new node.
addLast(): insert an element saved to the new node after the current tail of the linked list.
The next pointer of the current tail will point to the new node and the previous pointer of
the new node point to the current tail. The new tail now is set to the new node.
Insert(): traversal and find the previous index node and set the next pointer of this node to
the new node as well as set the previous of the new node point to the previous index
node. The next pointer of the new node is set to the next pointer of the previous node and
set the previous pointer of the node at the next pointer of the new node to the new node.
Page 7 of 35
removeFirst(): set the head pointer to the next node of the current head and set the next
pointer of this one to null. The head node now also is set its previous pointer to null.
removeLast(): from the last node, back to the previous node via the previous pointer. Set
the next pointer of the previous node to null and set the previous pointer of the last node
as null. The tail pointer now points to the previous node.
size(): return the size instance variable which is updated constantly whenever one change
of data in the linked list happens.
isEmpty(): if size is equal to 0, return true and vice versa.
getFirst(): return the first pointer if the linked list Is not null
getLast(): return the last pointer if the linked list Is not null
Search(): traversal by looping via each element to find the element at the correct index and
return this one.
Sort(): apply the merge sort algorithm to sort the list ascendingly.
1.3. Implement Singly and Doubly Linked-List
To demonstrate the implementation of the Singly-Doubly linked list, here are some code screenshots
with the brief explanation of each function which have been written clearly in the code comment.
a) Implement Singly Linked-List:
Node class:
Figure 1: Node structure of singly linked list
Singly linked list instance variables and constructor:
Page 8 of 35
Figure 2: instance variables and constructor of linked list
addLast Operation and addFirst Operation:
Figure 3: addLast Operation and addFirst Operation of singly
Insert operation:
Page 9 of 35
Search Operation:
Figure 4: singly Insert operation
Figure 5: Singly Search Operation:
getFirst and getLast operation:
Figure 6:getFirst and getLast
operation
Page 10 of 35
RemoveFirst and RemoveLast Operation:
Figure 8: Singly RemoveFirst and RemoveLast Operation:
Size and isEmpty operation:
Figure 7: Size and isEmpty Operation of singly list
Page 11 of 35
b) Implement Doubly Linked List:
Node class
Figure 9: Node class of doubly linked list
Instance variables and constructor
Figure 10: Doubly linked list class
Page 12 of 35
addFirst and addLast operations:
Figure 12: addFirst and addLast operations of doubly
size and isEmpty operation of doubly
Figure 11: size and isEmpty operation of doubly
Page 13 of 35
Search operation:
Figure 13: search operation of doubly
Insert Operation:
Figure 14: Insert Doubly
Page 14 of 35
RemoveFirst and RemoveLast operation:
Figure 16: Remove First and Last Operation doubly
GetFisrt and GetLast operation:
Figure 15: GetFirst and Last doubly
Page 15 of 35
2. Insert An Element In The Middle Of A Linked-List
Although there are two terminologies of linked-list(singly and doubly), it could be said that the doubly
linked list is the upgraded version or extended version of the singly linked list. In other words, when I
implement one operation in the doubly linked list, this also means that I could implement it on the singly
linked list at an easier level. So, in this section, I will only show the implementation of inserting an
element in the middle for the double link list.
2.1. Implementation
Figure 17: InsertMiddle Doubly Linked List
2.2. Explanation of the implementation
To insert an element into the middle of doubly linked list, one of the crucial things is checking
whether the node data is null or not. If it’s null, throw error immediately. If the list is empty or the
size is equal to 1, it means this element inserted will be new head or new tail. One of the essential
steps is to find the previous element of the middle index(middle position of linked). This is because
the storing mechanism of a linked list is very different from the other data structure such as arraylist as well as array. It stores data in each node and each node has the pointers to join the next or
Page 16 of 35
the previous node. It means, it does not mark any index to the elements in this data structure
except two pointers to identify this linked list(head pointer and tail pointer).
To find the correct middle index to insert the element, this is necessary to pass via each element
and find the previous node(middle index - 1) and perform adjusting the pointer of this previous
node and also the next node of this one. To find the middle index, I need to check whether it is an
even or odd number. If it’s odd, increase the size to one digit and divide it by two(because the odd
integer number when separated will provide the not really exact number).
In my source code, the finding process is hidden because I use the search operation of this doubly
linked list adt. However, the real process of this could be described basically as creating the
prevNode variable to store and the count variable(called i) and a while loop to loop via the list until
it reaches the middle index – 1.
For more illustration, here is the visualisation of the searching previous node process. Assuming
the index that needs to be inserted is the middle index(size = 7, middleindex = 3(one other way will
take 4 is middle index but I prefer the way that calculate index is 3)) and the previous index is 2:
Figure 18: Searching the previous node
The loop passes via each element. Each element passed will be stored temporarily to the prevNode
and the I variable is increased via each time loop until the condition of the while loop does not
meet, and the loop stop looping. In the real implementation of my code, the search operation also
could traversal elements by two way(from tail or from head) based on the inserted index.
After finding the previous node, the next step is quite simple. It just needs to adjust the pointer of
the previous node and the next node of the previous node to the new node. In the code
Page 17 of 35
implementation screenshot, this step is written quite clearly; however, here is the visual illustration
of this process:
Continues with the illustration above, the index to insert is 3 and the data now is 43:
Apply newNode.setNext(prev.getNext()) and newNode.setPrev(prevNode):
Figure 19: adjust pointer of new node
Adjust the pointer of these beside nodes:
Figure 20: Complete Inserting process
When all the pointer next and prev of each node are pointing to the neccesary node as the
requirement of this operation. The operation is terminated with the node has new node inserted.
3. Sorting in Linked-List
3.1. Describe your selected sorting algorithm
To apply a sorting algorithm to sort the linked list, here are some suitable sorting algorithms such as
insertion sort and merge sort. However, insertion sort is considered and chosen to be the sorting
algorithm for my linked-lists sorting operation because of its easy implementation of this one.
Page 18 of 35
Insertion sort is viewed as a type of in-place comparison-based sorting algorithm. It uses the loop to
pass via elements of the linked list. Each iteration of this method removes an element from the input
data and puts it into the right location in the sorted linked list (Palaniappan, 2021). The element is
deleted from the input and is chosen at random, and the procedure is continued until all input items
have been processed.
3.2. Implementation
Figure 21: Sorting algorithm Implement
3.3. Explanation Of The Implementation
Besides explaining the particular code implementation, I would briefly describe the mechanism of
insertion sort and provide an illustrated visual for the sorting process. Generally, the basic working
Page 19 of 35
mechanism of insertion sort is that it picks the first element to assume it is located on the sorted
side, in the code implementation I pick the head pointer and assigned it to the picked node pointer.
To perform comparing between node and swap, the insertion sort mechanism will need to pick the
key in this list and in code implementation, this key is the currentNode. The program will perform
compare the first node and the key node. For instance, I have a doubly linked list as below:
Because this operation sorts ascendingly, if the pickedNode is greater than currentNode, the
program swaps them:
However, it’s only in terms of illustration. In real code implementation, instead of providing more
if-else statements or redundancy of unnecessary code, the condition is combined in a while loop.
Because after each loop, the picked Loop is set to the next node until it reaches the tail, the outside
while needs to come with the condition that it will run until the picked Node is null. And because
when the picked Node is not null, the current node is assigned to the next node of the picked node
according to the mechanism of insertion sort.
The condition in the nested while is quite abstracted; hence, I describe it via the illustrated visual
below:
Assuming now the picked node is the third node and the current node is after the picked node
Now because the current node is not null and the previous node of it also, the program performs
comparing these two. At the first glance, we can also see that 11 is less than 33; so, the condition
now is met(condition: current node and the previous node are not null, the previous node data of
a current node is less than the current node). It comes to the code inside the nested while, the
program will call swap operation to swap these two(just swap the data of node without swapping
their next and previous pointer).
Page 20 of 35
Because the mechanism of insertion sort is it will pick the current node and compare it with all the
elements of the sorted side(the side with the last element is the picked node). To follow that in
code implementation, the current node will be back to the previous node and the process will be
iterated until it doesn’t meet the condition of these two while loops. To illustrate, I continue the
above process:
Swap data of nodes in comparing above.
Continue setting the current node to the previous node and compare. If the previous is less than
the current node, swap them. If node, skip this loop and continue. This process will be executed
constantly until there are no previous nodes of the current node(the previous node is null now).
Page 21 of 35
Now looking at the position of the initial current node(after the picked node), from this to any
previous element is the sorted linked list. Thereby, the currentNode will be set to the fourth node
and the program continue the while loop until the linked list is absolutely sorted.
C. IMPLEMENT ERROR HANDLING AND REPORT TEST RESULTS
1. Testing Plan
In this section, I demonstrate some typical test cases in order to test the efficient feature of my linked
list. Thereby, I could provide the evaluation based on this testing plan and results:
Note Descriptions:
S1 -> the instance of the singly liked list
S2 -> the instance of the doubly linked list
No. Scope
Operation
Testing
Input
Expected
Actual
Status
Type
Output
Output
1.
Singly
addLast(T
Normal
S1[6,9];
S1:[6,9,69]
The same Passed
LinkedList
data)
addLast(69)
S1.size() = 3 as
ADT:
Search(2)
expected
My Singly
return 69
output
Linked List
getLast()
S1
return 69
2.
addFirst(T
Normal
S1[6,9];
S1:[69,6,9]
The same Passed
data)
addFirst(69)
S1.size() = 3 as
Search(0)
expected
return 69
output
getFirst()
return 69
3.
addLast(T
Data
S1[6,9];
S1: [6,9]
S1[6,9]
Failed
data)
validation addLast();
Throw error The
program
is
stopped
4.
addFirst(T
Data
S1[6,9];
S1: [6,9]
S1[6,9]
Failed
data)
validation addFirst();
Throw error The
program
is
stopped
5.
insert(T data) Data
S1[6,9]
S1:[6,9]
S1:[6,9]
Passed
validation addLast(69, 3)
Throw error Throw
error
6.
insert(T data) Data
S1[6,9]
S1:[6,9]
S1:[6,9]
Passed
validation addLast(69, -2)
Throw error Throw
error
Page 22 of 35
7.
insert(T data)
Data
validation
S1[6,9]
addLast(“oko”, 2)
S1:[6,9]
Throw error
8.
insert(T data)
Data
validation
S1[6,9]
addLast(836655 ,
null)
S1:[6,9]
Throw error
9.
removeFirst()
Data
validation
S1[]
removeFirst()
S1:[]
Throw error
10.
removeLast()
Normal
S1[6,9,69]
removeFirst()
S1:[6,9]
Return 69
11.
search()
Normal
S1[6,9];
Search(1)
S1[6,9]
Return 9
12.
search()
Data
validation
S1[6,9];
Search(6)
S1[6,9]
Throw error
addLast(T
data)
Normal
S2[6,9];
addLast(69)
14.
addLast(T
data)
Data
validation
S2[6,9];
addLast();
S2:[6,9,69]
S2.size() = 3
Search(2)
return 69
getLast()
return 69
S2: [6,9]
Throw error
15.
getFirst()
Data
validation
S2[];
getFirst
S2: []
Throw error
16.
addFirst(T
data)
Data
validation
S2[6,9];
addFirst();
S2: [6,9]
Throw error
13.
Doubly
LinkedList
ADT:
My doubly
Linked List
S1
S1:[6,9]
The
program
is
stopped
S1:[6,9]
The
program
is
stopped
The same
as
expected
output
S1: []
Throw
error
The same
as
expected
output
S1[6,9]
Throw
error
The same
as
expected
output
Failed
Failed
Passed
Passed
Passed
Passed
Passed
S2[6,9]
Failed
The
program
is
stopped
The same Passed
as
expected
output
S2[6,9]
Failed
The
program
Page 23 of 35
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Question b
is
stopped
insert(T data) Data
S2[6,9]
S2:[6,9]
S2:[6,9]
validation addLast(69, 3)
Throw error Throw
error
insert(T data) Data
S2[6,9]
S2:[6,9]
S2:[6,9]
validation addLast(69, “2”) Throw error The
program
is
stopped
insert(T data) Data
S2[6,9]
S2:[6,9]
S2:[6,9]
validation addLast(“oko”, - Throw error The
2)
program
is
stopped
isEmpty()
Normal
S2[1,8,12]
Return false Return
isEmpty()
false
insert(T data) Data
S2[6,9]
S2:[6,9]
S2:[6,9]
validation addLast(836655 , Throw error The
null)
program
is
stopped
removeFirst() Data
S2[]
S2:[]
The same
validation removeFirst()
Throw error as
expected
output
removeLast()
Data
S2[]
S2:[]
The same
validation removeLast()
Throw error as
expected
output
InsertMiddle(T Normal
S2[1,2,5,6]
S2:[1,2,4,5,6] The same
data)
InsertMiddle(4)
Size + = 1
as
expected
output
InsertMiddle(T Data
S2[1,2,4,5]
S2[1,2,4,5]
The
data)
Validation InsertMiddle(“3”) Throw error program
is
stopped
InsertMiddle(T Data
S2[1,2,4,5]
S2[1,2,4,5]
The same
data)
Validation InsertMiddle()
Throw error as
expected
output
Passed
Failed
Failed
Passed
Failed
Passed
Passed
Passed
Failed
Passed
Page 24 of 35
27.
Question c
Sort()
Normal
S2[1,2,6,4];
Sort()
28.
Sort()
Data
S2[];
Validation Sort
Throw error
29.
Sort()
Data
validation
Throw error
S2[1, “5”];
Sort
S2[1,2,4,6]
The same Passed
as
expected
output
The
Failed
program
is
stopped
The
Failed
program
is
stopped
2. Evaluation
2.1. Overall:
In the testing plan, 29 test cases have been performed. And the number of passed test cases is 17
and the number of failed test cases is 12.
2.2. Explain and Solution
Explanation:
Most failure cases come from the test case which involved the data validation; Specifically, they
almost are the checking argument of operation. This indicates that my code is very lacking in
appropriate checking processes. Although the checking conditions such as checking the list is empty,
checking the argument is not null in some operations or checking the index argument when
comparing with the size of the linked list, are not enough for the stable as well as accurate operation.
Some of the crucial checking conditions are not implemented such as checking whether the argument
is the expected data type, and checking whether the argument is null or not(most of the add
operation lack this checking condition). Additionally, one of the important checking conditions in the
sort operation is to check whether the data type of all elements in the linked list is the same or not.
Because I implement a linked list with the generic type(T), it’s possible to add different datatypes into
the linked list without declaring the data type.
Solution:
The good solution now is to enhance the checking argument process for all operations in both
singly and doubly linked lists. Particularly, start from some checking for the data type of
argument to set up fill the checking null argument for all add and insert operations. Although
the element of the linked list could be null, it should be avoided to ensure the proper working
mechanism. Additionally, checking the data type of all elements in the linked list also is
important for the sorting process. Set up the exact exception will be thrown when the argument
or the condition comes wrong.
Extend and add more test cases to the testing plan to trace and detect more failure cases and
then continue providing the appropriate solution.
Page 25 of 35