Assignment 2 Data Structure and Algorithms (1649) (điểm chuẩn Pass) năm 2022 đại học GW. Implement complex data structures and algorithms. Singly linked list and doubly linked list.The difference of singly linked list and doubly linked list. Implement singly linked list. Doubly linked list. Insert to middle of Linked list. Implement error handling and report test results. Testing plan. Discuss how asymptotic analysis can be used to assess the effectiveness of an algorithm. Theta Notation. Big O Notation. Omega Notation. Determine two ways in which the efficiency of an algorithm can be measured, illustrating your. P4 Implement a complex ADT and algorithm in an executable programming language to solve a well-defined problem. P5 Implement error handling and report test results. P6 Discuss how asymptotic analysis can be used to assess the effectiveness of an algorithm. P7 Determine two ways in which the efficiency of an algorithm can be measured, illustrating your answer with an example.
Trang 1Qualification BTEC Level 5 HND Diploma in Computing
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
Trang 2 Summative Feedback: Resubmission Feedback:
Internal Verifier’s Comments:
IV Signature:
2.1
Trang 3Contents
I Implement complex data structures and algorithms 2
1 Singly linked list and doubly linked list 2
1.1 The difference of singly linked list and doubly linked list 2
1.2 Implement singly linked list 2
1.3 Doubly linked list 5
2 Insert to middle of Linked list. 8
II Implement error handling and report test results 9
1 Testing plan 9
2 Evaluation 10
III Discuss how asymptotic analysis can be used to assess the effectiveness of an algorithm 11
1 Theta Notation 11
2 Big O Notation 11
3 Omega Notation 12
4 Example 12
IV Determine two ways in which the efficiency of an algorithm can be measured, illustrating your 13
V Reference 14
Trang 4List of figures
Figure 1: Structure of singly linked list and doubly linked list 2
Figure 2: class Node 3
Figure 3: addLast of Singly linked list 3
Figure 4: removeLast of singly 4
Figure 5: addFirst of singly 4
Figure 6: removeFirst of singly 5
Figure 7: toString of singly and doubly 5
Figure 8: class Node of doubly 6
Figure 9: addLast of doubly 6
Figure 10: removeLast of doubly 7
Figure 11: addFirst of doubly 7
Figure 12: removeFirst of doubly 8
Figure 13: insertMiddle of doubly 9
Figure 14: Example of Theta notation (GeeksforGeeks, 2022) 11
Figure 15: Example of Big O notation (GeeksforGeeks, 2022) 12
Figure 16: Example of Omega Notation (GeeksforGeeks, 2022) 12
Figure 17: Example of O(1) 13
Figure 18: Example of O(n) 13
Figure 19: Selection sort 13
Figure 20: Change input from 5 to 10 elements 14
List of tables Table 1: Compare Singly and doubly linked list 2
Table 2: Test plan 9
Trang 5I Implement complex data structures and algorithms
1 Singly linked list and doubly linked list
1.1 The difference of singly linked list and doubly linked list
Singly linked list and doubly linked list are both list data structures used to store program information, they are all built on the basis of Linked list structure, the elements are linked together by nodes
Figure 1: Structure of singly linked list and doubly linked list
Difference between Singly linked list and doubly linked list
Table 1: Compare Singly and doubly linked list
The elements are only joined by the next node,
ie the previous element is connected to the
following element, but not vice versa
Two-way join elements ie the following element will store the position of the element before and after it, both next and previous nodes exist Only one-way access from head to tail Can access from head to tail or tail to head
Requires 2 memory cells for each element Requires 3 memory cells for each element
The next pointer of the last element is null The next pointer of the last element is null and
the previous pointer of the first element is null Time complexity is large Time complexity is small
Space complexity is small Space complexity is larger than singly but not
significantly
1.2 Implement singly linked list
Initialize MyLinkedList with generic <T>
a Class Node
Trang 6Initialize the Node class to store the element's value and a next Node to store the next Node object The constructor takes as an input parameter T data, assigns Node's data equal to the parameter and Node next equals null
Figure 2: class Node
b addLast Operation
Singly Linked list has 2 Nodes, head and tail are null, head is the first element, tail is the last element This operation will add the element to the end of the list
If in case of list there is no element, assign head and tail equal to that Object Node (for first and last element are equal to new Node)
If the list already has an element, then assign tail.next = new Node, then assign tail = new Node (the next position of tail is new Node, then assign tail = new Node so that tail remains the last element)
Figure 3: addLast of Singly linked list
c removeLast Operation
If the function has no element, it cannot be deleted, so it will return null
Trang 7If the function has one element, assign both head and tail = null, then return the deleted value
head.data
In other cases, use a loop to move to the last element (next = null) and stop Before reaching the last element, there is an assignment to get the element near the end of the list
After the loop is over, assign next to the last element = null, assign tail = the last element, and then return the deleted value
Figure 4: removeLast of singly
d addFirst operation
The function adds to the head with the parameter T data, initializes the Node with the data parameter, assigns that Node's next = head and assigns head = new Node It will basically replace the head element with the new Node and set next to the old head
Figure 5: addFirst of singly
e removeFirst operation
Trang 8Function to remove the first element, if the list is empty, return null, if the list has an element, use the intermediate variable tmp to store the head, assign head = the 2nd element then assign the next of tmp
= null, returns the deleted data value It cuts the link between 2 elements and assigns the 2nd element to the first element
Figure 6: removeFirst of singly
f toString
This function will use a loop to print out all the elements of the list as a string so that the user can check the array
Figure 7: toString of singly and doubly
1.3.Doubly linked list
Because doubly and singly are quite similar, I will explain the differences Like the Singly linked list, this function also has a Node class to store data, the next Node, in addition, it has an additional Node previous to store the previous Node
Trang 9Figure 8: class Node of doubly
Like Singly's addLast, the only difference is that it assigns the previous of the newly added Node with the old Node tail Once done, increase the value of size
a addLast Operation
Like Singly's addLast, the only difference is that it assigns the previous of the newly added Node with the old Node tail Once done, increase the value of size
Figure 9: addLast of doubly
b removeLast operation
It is quite similar to singly, the difference is:
- In case there is 1 element, after the deletion is done, the size will decrease by 1
- In case of multiple elements, the element near the end will also be saved and assigned next = null, however, there is no need to use a loop to go from head but can go backwards from tail back with previous
Trang 10Figure 10: removeLast of doubly
c addFirst operation
The difference is that the previous head of the old head will be assigned to the new Node and increase the size value by 1
Figure 11: addFirst of doubly
d addLast operation
The difference is that previous of the last element and next of the last element will be set to null to cut off the link between it and the last element Assign tail with the Node near the end, then reduce the size
by 1
Trang 11Figure 12: removeFirst of doubly
Also it has a method called toString but it's not different from Singly so I won't mention it again
2 Insert to middle of Linked list
To insert in the middle of the list, you must know the number of elements in the list, then go to that position and insert To perform the insertion, a Doubly linked list is used I will show some methods to insert in the middle of the list
- Method 1: use a loop to go from head to the middle element and assign next of the element before it
and previous of the element after it equal to it (new element) Then assign its previous to the element before it and next to the element after it
- Method 2: Similar to method 1, but using a loop from tail
My method is method 1
Solution: In case the list is empty, call the addFirst operation to do it
In other cases, find the middle of the list with the formula: size/2 + 1
Create a variable that stores the starting position of the list (from the first element)
Use a loop with an iterator where the position variable is not larger than the size variable
When these two variables are equal, that is, they are in the middle position, they will assign previous of the middle element (Node middle) and the next of the previous element (Node before) with the new Node, then assign the previous of the new Node with the Node before and next = Node middle Increase the value of size by 1
Trang 12Figure 13: insertMiddle of doubly
1 Testing plan
Table 2: Test plan
No Scope Operation Testing
type
Input Excepted output Actual output Status
1 SinglyLink
edList
ADT:
MyLinked
List S1
addLast(Element E)
Normal S1: [3,2,5]
addLast(9)
S1: [3,2,5,9]
Print S1 = “3 2 5
9 ”
As expected
Passed
E)
Normal S1: [3]
addLast(6)
S1: [3,6]
Print S1 = “3 6 ”
S1: [6,3]
Print S1 = “6
3 ”
Failed
a= removeLast()
S1: [3,2,5]
a = 9
As expected
Passed
a = removeLast
a = null NullPointerE
xception
Failed
E)
Normal S1: [3,2,5]
addFirst(9)
S1: [9,3,2,5]
Print S1 = “9 3 2
5 ”
As expected
Passed
removeFirst()
S1: [3,2,5]
a= 9
As expected
Passed
Trang 137 removeFirst() Validation S1: []
a = removeFirst()
a = null NullPointerE
xception
Failed
8 DoublyLin
kedList
ADT:
DoublyLin
kedList
addLast(Element E)
Normal S1: []
addLast(9)
S1: [9]
Print S1 = “9 ”
As expected
Passed
E)
Normal S1: [3,7,9]
addLast(6)
S1: [3,7,9,6]
Print S1 = “3 7 9
6 ”
S1: [3,7,9]
Print S1 = “3
7 9 ”
Failed
a= removeLast()
S1: [3,2,5]
a = 9
As expected
Passed
11 removeLast() Validation S1: []
a = removeLast
E)
Normal S1: [1,2,3]
addFirst(9)
S1: [9,1,2,3]
Print S1 = “9 1 2
3 ”
As expected
Passed
removeFirst()
S1: [1,2,3]
a= 9
As expected
Passed
14 removeFirst() Validation S1: []
a = removeFirst()
expected
Passed
15 Question b insertMiddle(Ele
ment E)
Normal S1:[1,2,3,4,5,6]
insertMiddle(7)
S1:[1,2,3,7,4,5,6]
Print S1 = “1 2 3
7 4 5 6 ”
S1:[1,2,7,3,4, 5,6]
Print S1 = “1
2 7 3 4 5 6 ”
Failed
ment E)
Normal S1: []
insertMiddle(8)
S1:[8]
Print S1 = “8 ”
S1:[]
Print S1 = “”
Failed
2 Evaluation
The test cases are recorded according to the execution process, so the failure cases have been fixed in the implementation part, the source code is the source code after fixing the errors in the test plan
Out of 16 test cases executed, 6 failed, most of the cases were test validation of the operation
The data shows that validations often occur when the list is empty which in turn leads to failed functions
In the program, the error is found to not perform the empty list condition check, which leads to error cases For example, when a list has no elements, assignments to remove the element cannot be performed, thus creating an Exception NullPointerException which causes the program to stop unexpectedly or cannot perform adding the element leaving the element unchanged
Trang 14Also, in question b, the formula for the middle position is wrong, causing the element to be inserted incorrectly
Solution: add conditional statements to check if the list is empty or not, modify the middle formula
Asymptotic analysis is simply understood as a method of calculating the performance of an algorithm, how it affects the program in time or space, finding a most general formula for all the algorithms program, from which there will be a suitable application for each program
It is usually classified into worst case (worst case), average case (average case) and best case (best case)
1 Theta Notation
Theta Notation is bounded around the upper and lower bounds of the algorithm (GeeksforGeeks, 2022),
so it represents the 2 limits of the algorithm, from which the average running time of the algorithm is calculated From there, it is applied to find the average case of the algorithm Average case is the average time of each run of an algorithm, so Theta Notation is the right choice to analyze the average case of the algorithm
Figure 14: Example of Theta notation (GeeksforGeeks, 2022)
2 Big O Notation
Like Theta Notation, Big O Notation is also used for asymptotic analysis of algorithms Big O is the method of analyzing the upper limit of an algorithm (GeeksforGeeks, 2022), so it is applied to calculate the worst case for the algorithm This method calculates the maximum number of statements or functions
to be executed of an algorithm, thereby figuring out their dependence on the input Finally, give the result of the worst case
Trang 15Figure 15: Example of Big O notation (GeeksforGeeks, 2022)
3 Omega Notation
Omega Notation is used to analyze the lower asymptote of an algorithm so it is used for the best case analysis of an algorithm (GeeksforGeeks, 2022) An algorithm with a small best case will have a very fast running speed when entering a good case However, it is not used too much because most developers only care and optimize the worst case
Figure 16: Example of Omega Notation (GeeksforGeeks, 2022)
4 Example
The Big O Notation asymptotic analysis method will be used to calculate the Worst case of some algorithms
a O(1)
Trang 16Figure 17: Example of O(1)
A simple algorithm to check that n is divisible by 2, the if statement is executed at most and it is 1 time, even if n = 4, 5, 6 changes, the number of if runs does not change so it does not depend on n
We have the worst case of this algorithm as O(1)
b O(n)
Figure 18: Example of O(n)
Algorithm prints numbers from 0 to n, print statement will be run n times, so it depends on n so worst case of this algorithm is O(n)
your
Selection sort algorithm
Figure 19: Selection sort
The time complexity of selection sort is calculated as the maximum number of times if(arr[min] >
arr[j]) is executed We will consider 2 loops, the first loop runs (4) times, the second loop runs 4 times Hence T(5) = 4*4 = 16 times
When input increments from 5 elements to 10 elements
Trang 1714
Figure 20: Change input from 5 to 10 elements
The first loop is run 9 times, the second loop is 9 times T(10) = 9*9 = 81
We see the general formula of T(n) = (n-1) * (n-1) so the Complexity of the selection sort is O(n2) Time complexity will increase with the order of squares for the number of input elements
The space complexity of the selection sort will consist of two parts: the number of input cells and the number of generated memory cells Most devices today are 64bit, Ram 8, 16GB, so an int memory cell will occupy 8bytes, bool takes up 1 byte in RAM
The input storage capacity of 5 elements is: 5*8bytes = 40 bytes
The generated capacity: includes variables i, j, arr.length, arr.length – 1,min, j, temp, 2 boolean variables
of the conditional => 58 bytes
When element increments from 5 to 10:
The input storage capacity of 10 elements is: 10*8bytes = 80 bytes
The generated capacity: includes variables i, j, arr.length, arr.length – 1,min, j, temp, 2 boolean variables
of the conditional => 58 bytes
We see that the generated capacity does not change despite increasing the number of input elements Increased input storage is something that happens in all algorithms, so we'll ignore them
So the conclusion is that the Space complexity of the selection sort is O(1) which means it doesn't change even if the input changes
GeeksforGeeks 2022 What are Asymptotic Notations in Complexity Analysis of Algorithms [online]
Available at: https://www.geeksforgeeks.org/analysis-of-algorithms-set-3asymptotic-notations/
(Accessed 31 August 2022)