Download as pdf or txt
Download as pdf or txt
You are on page 1of 54

ASSIGNMENT 1 FRONT SHEET

Qualification BTEC Level 5 HND Diploma in Computing

Unit number and title Unit 19: Data Structures and Algorithms

Submission date 25/04/2021 Date Received 1st submission 25/04/2021

Re-submission Date Date Received 2nd submission

Student Name Dinh Huy Hoang Student ID GCH190440

Class GCH0804 Assessor name Do Hong Quan

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

P1 P2 P3 M1 M2 M3 D1 D2
 Summative Feedback:  Resubmission Feedback:

Grade: Assessor Signature: Date:


Internal Verifier’s Comments:

IV Signature:
Table of contents

Introduction.................................................................................................................................................... 6

Part 1............................................................................................................................................................... 6

1. ADT (P1)............................................................................................................................................... 6

2. Stack ADT (P1)......................................................................................................................................7

2.1 What is stack?.............................................................................................................................7

2.2 Stack operations and working mechanism................................................................................ 8

2.3 Application/ Examples of Stack.................................................................................................. 9

3. Memory stack (P2).............................................................................................................................11

4. Queue ADT (P1 + M1)....................................................................................................................... 13

4.1 What is queue?........................................................................................................................ 13

4.2 Queue operations.....................................................................................................................13

4.3 An example/ applications applied data structure FIFO queue................................................ 15

5. Sorting algorithms (M2).....................................................................................................................16

5.1 Introduction..............................................................................................................................18

5.2 Selection sort........................................................................................................................... 20

5.3 Counting Sort............................................................................................................................24

6. Two networks shortest path algorithms (D1)....................................................................................33

Problem solving..............................................................................................................................33

6.1 BFS............................................................................................................................................ 34

A. Pseudo code........................................................................................................................34

B. Example...............................................................................................................................36

6.2 Dijkstra algorithm.....................................................................................................................39

A. Steps to implement.............................................................................................................39
B. Example...............................................................................................................................40

Part 2.............................................................................................................................................................45

1. Explanation on how to specify an abstract data type using the example of software stack (P3).... 45

2. Explanation of the advantages of encapsulation and information hiding when using an ADT (M3)47

2.1 Encapsulation........................................................................................................................... 47

2.2 Why we need encapsulation?.................................................................................................. 48

2.3 Advantages and information hiding when using an ADT Encapsulation uses accessors and
mutators Encapsulation using properties.......................................................................................48

3. Discussion of imperative ADTs with regard to object orientation (D2)............................................ 50

Evaluation (D2)..............................................................................................................................................52

References.................................................................................................................................................... 53

List of Figures

Figure 1 : Abstract Data Type (Chauhan, 2019).............................................................................................. 6

Figure 2 : Stack (Wuyn, 2021)......................................................................................................................... 7

Figure 3 : Push operation in stack (Wuyn, 2021)............................................................................................8

Figure 4 : Pop operation in stack (Wuyn, 2021)............................................................................................. 8

Figure 5 : Peek operation in stack (Wuyn, 2020)............................................................................................9

Figure 6 : Example using stack...................................................................................................................... 10

Figure 7 : Example when calling stack in memory........................................................................................12

Figure 8 : Queue (Blake, 2021)......................................................................................................................13

Figure 9 : Enqueue operation in queue (Wuyn, 2021)................................................................................. 13

Figure 10 : Dequeue operation in queue (Wuyn, 2021)............................................................................... 14

Figure 11 : Front and rear in queue (Bothra, 2019)......................................................................................14

Figure 12 : Example of queue....................................................................................................................... 15


Figure 13 : Flowchart selection sort..............................................................................................................20

Figure 14 : Source code selection sort..........................................................................................................24

Figure 15 : Flowchart counting sort.............................................................................................................. 25

Figure 16 : Source code counting sort.......................................................................................................... 32

Figure 17 : Graph data structure (Arikia, 2018)............................................................................................ 33

Figure 18 : Implementation stack using array.............................................................................................. 49

List of tables

Table 1 : Compare complexity of sorting algorithms....................................................................................16

Table 2 : Compare limits and performance of sorting algorithms................................................................18

Table 3 : Compare counting sort and selection sort.....................................................................................19

Table 4 : Shortest path Dijkstra algorithm....................................................................................................44


Introduction

In this report, I divide two part. In part 1, I will describe about specification for data structure as Stack,
Queue and Graph data structure , their operations and their examples (applications) of this data
structures. In part 2, I will show on how to specify an abstract data type and then I also give my opinions
in ADT vs OOP.

Part 1

1. ADT (P1)

According to Chauhan (2019), abstract data type (ADT) is a type (or class) for objects whose behaviour
is defined by a set of value and a set of operations on those values.

In ADT, it only mentions what operations are to be performed but not implement how it access these
operations. It does not show how data was be accessed and organized in memory and what algorithms
were used to implement the operations. So it named “abstract” because whose representation is
hidden from the client.

Figure 1: Abstract Data Type (Chauhan, 2019)


2. Stack ADT (P1)

2.1 What is stack?

According to Chauhan (2019), stack is a type container adaptor was designed accessing follow LIFO (Last
- in - first - out). It means a type of list and adding and removing an element is displayed at the end of
the list. The last element of stack called top of stack.

﹣ In Stack ADT Implementation instead of data being stored in each node, the pointer to data is
stored.
﹣ The program allocates memory for the data and address is passed to the stack ADT.
﹣ The head node and the data nodes are encapsulated in the ADT. The calling function can only see
the pointer to the stack.
﹣ The stack head structure also contains a pointer to top and count of number of entries currently in
stack.

Figure 2: Stack (Wuyn, 2021)


2.2 Stack operations and working mechanism

﹣ Boolean Push (item i): Return boolean data type - Insert an element at the end of the stack called
top. Return true if this happened else return false.

Figure 3: Push operation in stack (Wuyn, 2021)

﹣ Integer Pop (): Return int data type - Remove and return the element at the top of stack, if it is not
empty. Return element at the of stack if this happened else return null.

Figure 4: Pop operation in stack (Wuyn, 2021)


﹣ Integer Peek (Top): Return int data type - Return the element at the top of the stack without
removing it if the stack is not empty. Return element at the of stack if this happened else return null.

Figure 5: Peek operation in stack (Wuyn, 2020)

﹣ Int size(): Return int data type - Return amount of elements in the stack.

﹣ Boolean isEmpty(): Return boolean data type - Return true if the stack is empty else false.

﹣ Boolean isFull(): Return boolean data type - Return true if the stack is full else false.

All operation and working mechanism access with time complexity O(1) and space complexity depends
on size of the stack.

2.3 Application/ Examples of Stack

Some applications using stack

﹣ Expression evaluation: using stack to check prefix, postfix, infix expressions are right or not.

﹣ Syntax parsing: using stack to check expressions, programs block during executing in compiler.
﹣ Backtracking: for example, when find a path in maze, using stack to check if this road is wrong, we
need to go back to the beginning path to start new path.

﹣ Function call: stack is used to store functions in program.

﹣ Reverse string: push character into stack then display them and pop at the same time.

An simple example applied Stack is “Reverse a String”. Imagine that a string is an array of characters.

Step 1: Push each character of string into stack.

Step 2: Display top of stack, at the same time execute pop until the stack is empty.

Figure 6: Example using stack


3. Memory stack (P2)

According to Griffin (2019), Memory is one important and crucial resource on computer. It was applied
to know architecture of memory and the way operating. Memory stacks are linear data structures
(locations) used to store data in a computer's memory. Items in a stack are added or removed in a linear
order and not in any random sequence. In stack, a technique called LIFO (Last - in - first - out) is used.

Memory stack is where stored all information functions called and the local variables were built in
programs. And in stack functions will be stacked on top of each others.

 The operations of a memory stack

﹣ Push: Adds an item in the stack. If the stack is full, then it is said to be an Overflow condition.

﹣ Pop: Removes an item from the stack. The items are popped in the reversed order in which they
are pushed. If the stack is empty, then it is said to be an Underflow condition.

﹣ Peek (top): Returns top element of stack.

﹣ isEmpty: Returns true if stack is empty, else false.

﹣ isFulll: Returns true if the stack is full, else false.

 How it is used to implement function calls in a computer

A function is a set of code that performs a specific task and can be used whenever needed just by calling
it. While using multiple function calls or recursion, the concept of a function call is very necessary to be
known, for better understanding of the code.

Actually in application’s memory, a program was stored and divided 4 parts: Heap memory, Stack
memory, Static/ Global, Code (Text). But in this report, I will discuss about memory stack work.

In stack memory includes: functions call and local variables. Some prerequisite in programming
execution in the CPU: Program Stack, Stack Frame.
﹣ Program Stack: Program Stack is the stack which holds all the function calls, with bottom elements
as the main function.

﹣ Stack Frame: Stack Frame is actually a buffer memory that is an element of program stack and has
data of the called function: return address, input parameter, local variables, register savings.

Now, I will present how memory stack stored and called a program: calculate factorial of numbers by
applied recursion.

Figure 7: Example when calling stack in memory


4. Queue ADT (P1 + M1)

4.1 What is queue?

According to Blake (2021), Queue is a type container follows the basic design of the stack ADT and was
designed accessing follows FIFO (First - in - first - out). It means the addition will be executed at last
and removed at first.

Each node contains a void pointer to the data and the link pointer to the next element in the queue.
The program’s responsibility is to allocate memory for storing the data.

Figure 8: Queue (Blake, 2021)

4.2 Queue operations

﹣ Boolean Enqueue (item i): Return boolean data type - Insert an element at the end of queue. Return
true if item i added else false

Figure 9: Enqueue operation in queue (Wuyn, 2021)


﹣ Integer Dequeue (): Return object Integer - Remove and return the first element of the queue, if the
queue is not empty. Return value at front if this happened else return null.

Figure 10: Dequeue operation in queue (Wuyn, 2021)

﹣ Integer Front(): Return object integer - Accessing and return the first element of the queue if the
queue is not empty. Return value at front if this happened else return null.

﹣ Integer Rear(): Return object integer - Accessing and return the last element of the queue if the
queue is not empty. Return value at rear if this happened else return null.

Figure 11: Front and rear in queue (Bothra, 2019)


﹣ Int size(): Return int data type - Return amounts of elements in the queue.

﹣ Boolean isEmpty(): Return boolean data type - True if empty else false.

﹣ Boolean isFull(): Return boolean data type - True if full else false.

4.3 An example/ applications applied data structure FIFO queue

Some applications using queue

﹣ Serving requests on a single shared resource, like a printer, CPU task scheduling.

﹣ In real life scenario, call center, message queue, mail queues, routers, switches systems uses Queues
to hold people calling them in an order, until a service representative is free.

﹣ Handling of interrupts in real-time systems. The interrupts are handled in the same order as they
arrive. First comes first served.

Message queue applied queue. The messages will be pushed on a first-in-first-out basis. Queue storage
will help the user see the content of the most recent messages that will be displayed at the top.

Figure 12: Example of queue


5. Sorting algorithms (M2)

 The purpose of sorting

According to Sedgewick (2011), sorting is the process of rearranging a sequence of objects so as to put
them in some logical order. For example, your credit card bill presents transactions in order by date -
they were likely put into that order by a sorting algorithm. The purpose of this sorting will help us can
check and manage credit card bill easily in bad cases happen or in order to evaluate favorite items or not.
Another purpose of sorting in computing is when using e-commerce sites, when you search for products
within a budget. Here comes sorting to fit into the range. When you have a hundreds and thousands of
items or even a small list of items, it is good to have them organized in an order based on your needs so
that you can easily select one.

Time complexity
Sorting algorithms Space complexity
Best case Average case Worst case

Bubble Sort O(n) O(n^2) O(n^2) O(1)

Selection Sort O(n^2) O(n^2) O(n^2) O(1)

Insertion Sort O(n) O(n^2) O(n^2) O(1)

Quick Sort O(nlog(n)) O(nlog(n)) O(n^2) O(log(n))

Merge Sort O(nlog(n)) O(nlog(n)) O(nlog(n)) O(n)

Counting Sort O(n+k) O(n+k) O(n+k) O(k)

Table 1: Compare complexity of sorting algorithms

 Compare different sort algorithms, explaining their limits and performance

Sorting algorithms Limits Performance

Bubble Sort ﹣ Run slow because time ﹣ This algorithm is fastest on an


complexity average and worst is extremely small or nearly sorted
O(n^2), best case is O(n) set of data
﹣ Quite stability and easy to set up
﹣ Not suitable for big data
because time to execute is too ﹣ Stops after reaching a sorted array
late
﹣ Can find the maximum number
with time complexity O(n)

Selection Sort ﹣ Run slow because time ﹣ This algorithm is fastest on an


complexity is O(n^2) extremely small or nearly sorted
set of data
﹣ Not suitable for big data
because time to execute is too
﹣ Easy to set up
late
﹣ Still run the entire array although
﹣ Memory space is limited
array sorted
because it makes the minimum
possible number of swaps ﹣ Can calculate min swaps times to
during sorting sorted an array
﹣ It’s not stability
Insertion Sort ﹣ Run slow because time ﹣ This algorithm is fastest on an
complexity average is O(n^2) extremely small or nearly sorted
set of data
﹣ Not suitable for big data
because time to execute is too
﹣ Quite stability and easy to set up
late
﹣ In the best case (already sorted), it
has fast running

Merge Sort ﹣ In array, space complexity is ﹣ Run fast on large data


O(n) but in linked list, it will be
﹣ Can be applied to sort in linked list
depended on
﹣ Where random access can be ﹣ The merge sort is stability, the
very, very expensive compared elements compared equally retain
to sequential access. their original order

﹣ Time complexity is faster -


O(nlog(n))

Quick Sort ﹣ In sort processing, the quick ﹣ Run fast on medium data not too
sort is not stability large data
﹣ In worst case, time complexity
﹣ Time complexity is faster -
is O(n^2)
O(nlog(n))
﹣ Where random access can be
very, very expensive compared
to sequential access.
﹣ Not suitable for sorting in linked
list because size of array is
flexed
Counting Sort ﹣ Can not apply in negative ﹣ Really fast because time complexity
numbers is O(n)
﹣ If max value minus min value is
﹣ Do not use compare between two
big, it will make over memory,
values and swaps to sort
most not use
﹣ Can not use in linked list ﹣ Using frequency and index of each
elements in array to sort

Table 2: Compare limits and performance of sorting algorithms

5.1 Introduction

﹣ What is sorting algorithms?

According to Sedgewick (2011), sorting is the process of rearranging a sequence of objects so as to put
them in some logical order. The fundamental task is to put the items in the desired order so that the
records are re-arranged for making searching easier. For example in science, to sort a series of
numbers from small to big. We will double-arrange one number so that the number in front is always
less than the number that comes after.
There are some popular sorting algorithms. In basic includes bubble sort, selection sort, insertion sort
and for advance includes merge sort, quick sort, counting sort, heap sort… So in part 5.2 and 5.3 I will
describe about selection sort and counting sort.

The reasons I choose this sorting algorithms to describe are the performance, pros and cons of them.

Performance Pros Cons

Selection sort ﹣ Be applied in sorting for ﹣ Can find the best ﹣ It’s slow to sort with
small data minimum and big data and not
calculate min swaps suitable
﹣ Using compare and
to sort
swaps to sort ﹣ It’s not stability
﹣ Easy to understand because it can
﹣ Time complexity is
idea and code change order of the
O(n^2) in every cases
implementation same value
﹣ Space complexity O(1)
﹣ In every case, time
complexity is O(n^2)

Counting sort ﹣ Be applied in sorting for ﹣ It’s fast to sort if can ﹣ It’s not suitable for
positive numbers and control value max max value minus min
max value minus min and min value is to big
value is not too big
﹣ Can calculate ﹣ Can not apply for
﹣ Using index and frequency of each negative numbers
frequency to sort elements
﹣ It’s stability
﹣ Time complexity: O(n+k) ﹣ Easy to understand

idea and code
﹣ Space complexity: O(k),
implementation
k is the size of count
array

Table 3: Compare counting sort and selection sort


5.2 Selection sort

 Flowchart

Figure 13: Flowchart selection sort


 Steps to implement

Step 1: Find the smallest element. Swap it with the first element.
Step 2: Find the second-smallest element. Swap it with the second element.
Step 3: Find the third-smallest element. Swap it with the third element.
Step 4: Repeat finding the next-smallest element, and swapping it into the correct position until the array
is sorted.

 Pseudo code

procedure selection sort

arr: array of items


n : size of array

for i = 0 to n - 1:

min_idx = i

for j = i+1 to n

if arr[j] < arr[min_idx] then

min_idx= j;

end if

end for

swap arr[min_idx] and arr[i]

end if

end for

end procedure
 Example sorting algorithm applied selection sort

Input: arr = [4, 3, 1, 5, 7, 9, 6, 2]

Expected output: arr = [1, 2, 3, 4, 5, 6, 7, 9]

Explanation:

Blue numbers are index in array. Green numbers which are sorted right position. Brown numbers which
are smallest values in array.

First, I will set elements from 0 to size of array - 1. In this array, it means set elements from 0-7. Then I
will find the smallest number in range 0-7. Here is number “1” is the smallest in brown.

Next, we will swap smallest number “1” in brown to a[0]. Right now, “1” is sorted right position in green
box.
Next, find the smallest in range 1-7. Here is number “2” is the smallest in brown.

We will swap smallest number “2” in brown to a[1]. Right now, “2” is sorted right position in green box.

Next, find the smallest number in range 2-7. Here is number “3” is the smallest in brown.

Next, swap smallest number “3” in brown to a[2]. Right now, “3” is sorted right position in green box.

Steps above will repeat again and again until all box is green, it means all numbers sorted in right
position. And the array now is
 Implementation

﹣ Data structure used: Array

﹣ Time complexity: O(n^2) in every case

﹣ Space complexity: O(1)

 Source code

Figure 14: Source code selection sort

5.3 Counting Sort


 Flowchart

Figure 15: Flowchart counting sort


 Steps to implement

Notice: For counting sort, all numbers must be integer greater than or equals to 0. Because counting sort
is implemented base on index (be integer greater than or equals to 0) of each elements in arrays to sort.

Step 1: Find max, min of original array named “arr”.

Step 2: Initialize new array named “countArr” with size = max + min - 1 to store frequency elements of
array “arr”.

Step 3: Initialize array “result” has size equals original array to store right position and value after sorted.
Change elements in array “countArr” to store position of each elements into array “result”.

Step 4: Assign elements in array “result” base on value and index of array “countArr”.

Step 5: Copy value from array “result” to original array.

 Pseudo code

procedure counting sort

arr: array of items


n : size of array
min: value min in array
max: value max in array
countArr: array store frequency values in arr
result: array store right sorted arr
size_countArr: max - min + 1

/* store frequency of numbers appear in arr to countArr*/


for i = 0 to n - 1:

countArr[arr[i]-min] ++

end for

/* store amount of numbers can be appear in arr to countArr from right to left*/

for i = 1 to size_countArr:

countArr[i] += countArr[i-1]
end for

for i = 0 to n-1:

Result[countArr[arr[i]-min]-1] = arr[i]

countArr[arr[i]-min] --

end for

for i = 0 to n-1:

arr[i] = result[i]

end for

end procedure

 Example sorting algorithms applied counting sort

Input: arr = [4,3,4,1,2,3,2,3,1]

Expected output: arr = [1,1,2,2,3,3,3,4,4]

Explanation:

We have original array

Here you can see max = 4 and min = 4 in original array so we have array “CountArr” have size = max -
min + 1 = 4 - 1 + 1 = 4. Why size = max - min + 1? Because we must get range both not range half to
store enough value in range [min,max]. Now in array “CountArr” will stored frequency numbers
appeared in original array based on index.

Follow the picture above, it means in original array: number 1 appeared 2 times, number 2 appeared 2
times, number 3 appeared 3 times, number 4 appeared 2 times.

Initialize array “result” to store right position/index of original array must sort. So array “result” have size
= original array’s size

Next, we will update array “CountArr” to store position/index of original array into array “result” by
countArr[i] += countArr[i-1]. Why it is countArr[i] += countArr[i-1]? Because it helps in put elements into
the correct index of the sorted array (original array). More, now we can know there will be how many
elements will be in for each element from right to left of array (I feel it is easier than left to right).
Now we have 3 arrays bellow:

Next, follow left to right [0, n-1] in original array, we will put numbers into array “result” follow this way:
result[countArr[arr[i]-min]-1] = arr[i]; countArr[arr[i]-min]--. This formula is quite easy to understand, it
will find and put numbers in original array then put it on array “result” based on values and indexes in
array “countArr”.
Next, we will find where is index of arr[1] in array “result”

Now in array “result” green box is sorted and put in right position, it means they are fixed. But in the
picture above when find and put position for arr[1], you can see the different for arr[0]. It is the
difference in array “countArr”. Value in index 3 of array minus 1 from 9 goes down 8. Because this step
will make numbers which are not sorted will be sorted in right position, because numbers are sorted in
array “result” are fixed.

For arr[0]

For arr[1]
Next, we will find where is index in array “result” for arr[2]

This steps will do again and again while i>n-1 and the array “result” will be

Now we, will copy from array result to original result

 Implementation

﹣ Data structure used: Array

﹣ Time complexity: O(n + k), k = max in array - min in array + 1

﹣ Space complexity: O(k) , k = max in array - min in array + 1


 Source code

Figure 16: Source code counting sort


6. Two networks shortest path algorithms (D1)

Problem solving

﹣ What is graph data structure?

A Graph is a non-linear data structure consisting of nodes and edges. The nodes are sometimes also
referred to as vertices and the edges are lines or arcs that connect any two nodes in the graph (Arikia,
2018).

Figure 17: Graph data structure (Arikia, 2018)

﹣ Usage of graph

Graph is used to show networks that related. The networks may include paths in a city or telephone
network or circuit network. Graphs are also used in social networks like LinkedIn, Facebook... For
example, in Facebook, each person is represented with a vertex(or node). Each node is a structure and
contains information like person id, name, gender, locale…

﹣ Describe problem

In this problem, I will show how to find the shortest path from this node to other node that they are not
on the same edges. To implement I will apply two algorithms: BFS (Breath First Search) and Dijkstra
algorithm. But in first problem, we don’t know exactly weight as distance between two points or the
total time to go to this point to other. So I set them equals to 1 to be easier in calculating. In second
problem, we will do with
6.1 BFS

A. Pseudo code

Procedure find shortest path using BFS

nodes: array 1D to store points


arr : array 2D to store adjacent point of each point
m : variable int to update number of label for each point when spreads to adjacent elements, at
first it will store starting position
label : array 1D to store number of label for each point
path : array 1D to store the shortest path in type number
start : variable int to store begin position in type number
end : variable int to store finish position in type number
m=0
/* assign all elements in label equals to -1*/
for i = 0 to label.length-1:

label[i] = -1

end for

/* start tick labels that follow the rules spreads to adjacent elements will increase by 1 unit*/

label[start] = m

while label[end] == -1:

for i = 0 to arr.length:

/* check label ticking or not and what label ticking is*/


if label[i] == m:

for j = 0 to arr.length:

/* check label not ticked and spreads to adjacent elements of element setting */
if label[j] == -1 and arr[i][j]==1:
/* increase by 1 unit for labels are checked */
label[i] = m + 1

end if

end for
end if

end for

m++

end while

/* the shortest path will have length equals to m + 1 because at first I set start point equals to 0 */
size of array path: m + 1

/* set the start point of path */


path[0] = start
/* set the finish point of path */
path[m] = end

/*find the path from the end point according to the rule of finding smaller number that have ticked
label equals to minus 1 adjacent spread until k > 1 because at 2 will find the position at 1 */

for k = m down to 1:

for j = 0 to arr.length:

/* check labels that equals label before minus 1 and it’s position are adjacent elements */

if label[j] == k - 1 and arr[path[k]][j] == 1:

/* if this label equals label before minus 1 then update element of path before */

path[k-1] = k

end if

end for

end for

/* print shortest path based on numbers (sign for each point) that store in path array */

for I = 0 to path.length:

print(nodes[path[i]])

end procedure
B. Example

Find the shortest path from point A to point E follow the image bellow. We set all distance of two point
that are adjacent equal. It means, we maybe see the length of point A to C is longer than others. But in
this problem, the length of point A to C equals to others.

Now when we see the picture above, we can easily to see the shortest path is “A C E” to go from A to E.
But how we use coding to implement it? I will share steps below to implement this algorithm.

At first, we are going to tick all label equals to -1. Actually, we can tick them any numbers but while
processing will be more complex or easier depends on how we tick them because tick them equal -1 will
help them imagine easier and friendly in calculating. More, I will set begin point equal to 0 to set next
point will be more clearly.

In summary, labels that ticked equals to -1 means they are not ticked rightly. And this labels need ticking.
Of course that the begin point is considered ticked equal to 0.

Now we have the path ticked follow the image below.


Now we are going to tick labels for each point follow the rules: spread adjacent point and increment
them by 1 unit from the previous label until the end point label is ticked. Point B and C are spread
adjacent point of point A

We will continue the step above. Point D and F are spread adjacent point of point B and point E is spread
adjacent point of point C.
According to the problem, we will find the shortest path from A to E. ie the starting point is A and the
ending point is E. and as I told above, we will tick labels for spread adjacent points until the ending point
ticked. You can see the picture above, now point E ticked equals to 2.

Ticking the labels for the end and stop will tell us two important features: the length of the shortest path
will be equal to the number to be ticked, and the number of points on the shortest path will be the
number to be ticked + 1.

Now from the ending point that is ticked, I will do the opposite of the above. It means, I will find adjacent
spread points from the ending point that has ticked labels after subtract 1 equals to ticked labels before.
This process will be accessed until all points are passed from the end to the beginning.

Now, we find point C is spread adjacent point when check it equals to ticked point after subtract 1.

Now, I find the shortest path is “A C E”. In this problem, only one path can find because other paths have
longer length. But in other problems, it will be able to have more than one path.
6.2 Dijkstra algorithm

A. Pseudo code

function Dijkstra(Graph, source):

for each vertex v in Graph: // Initialization

dist[v] := infinity // initial distance from source to vertex v is set to infinite

previous[v] := undefined // Previous node in optimal path from source

End for

dist[source] := 0 // Distance from source to source

Q := the set of all nodes in Graph // all nodes in the graph are unoptimized - thus are in Q

while Q is not empty: // main loop

u := node in Q with smallest dist[ ]

remove u from Q

for each neighbor v of u: // where v has not yet been removed from Q.

alt := dist[u] + dist_between(u, v)

if alt < dist[v] // Relax (u,v)

dist[v] := alt

previous[v] := u
End if
End if

End while

return previous[ ]
B. Example

Find the way is the shortest path from A to every point have shortest path. In this problem, we have
weight (distance) for two 2 adjacent points. Let’s try to find where is the shortest path from A to E.

Explanation

Firstly, I set all point from start equals to infinite. Why I need to do that? Because a infinite number is can
not be define, it means distance even is too long (999…999) can be defined will less than a infinite. So we
have
Now, I will set from start point equals to 0. And we change infinite of spread adjacent point of point A
equals to their distance. Green line is the way I am setting to find the path. Because AB < AC so I will set
the way in side AB until it’s path > AC I will transfer to set from AC.

Distance: AB = 10, AC = 15

Continue find distance of each point by adding up previous distance values. But now at point F and D, we
can see the distance from A greater than AC.

Distance: ABF = 25, ABD = 22


But now you can see AF > AC and AD > AC. So we will set the way transfer to AC. And find path from this
way. Blue line is the way to find path from side AC, now I get the distance from A to E follow the problem
requirement but I am not sure that this is the shortest path because AD < AD and AF < AE.

Distance: ACE = 25 (from side AC)

So, I continue to transfer to ABD to find the shortest path because ABD < ABF. More, ABF = 25 is greater
than or equals to ACE but ABF path is not stop, so I will not worry about this way. Now the way ABD
continues calculating to find the shortest way.
After calculating we get the distance ABDF = 23, ABDE = 24. It means the way ACE is wrong because it is
longer than ABDE (25>24). So now we have the temporary shortest path is ABDE. Why it’s only
temporary path. Because now ABDF = 23 (<24). We can not make sure that remaining distance of the
path ABDF >= (24 - 23 = 1).

So we continue to check if ABDFE is <=24 or not.


After calculating the path ABDFE = 28 > ABDE = 24. So we can make a last result that ABDE is the shortest
path.

To be more clearly in understanding, you can see the table below.

A B C D E F

∞ ∞ ∞ ∞ ∞ ∞

A 0 10 15 ∞ ∞ ∞

A,B - - 15 22 ∞ 25

A,C - - - 22 25 25

A,B,D - - - - 24 23

A,B,D,F - - - - 24 -

A,B,D,E - - - - - -

Table 4: Shortest path Dijkstra algorithm

Finally, we got the shortest path from A to E is A,B,D,E. Apart from, we can calculate all the shortest
paths from A. For example the shortest path from A to F is A,B,D,F.
Part 2

1. Explanation on how to specify an abstract data type using the example of software stack (P3)

 Stack

Stack s: named stack, n = size(): the length of stack, x = peek(): value at the top of stack, Max_Capacity:
max length of stack

isFull(): boolean - check stack is full or not

Pre-condition: None

Post-condition: size() == Max_Capacity

Error: None

Return: return true if stack is full else false

isEmpty(): boolean - check stack is empty or not

Pre-condition: None

Post-condition: size() == 0

Error: None

Return: return true if stack is empty else false

Push(item i): Boolean - Add a new item at the top of stack

Pre-condition: isFull() == False

Post-condition: size() == n + 1, top(s) == i

Error: isFull() == True, Stack Overflow

Return: return true if item added else false

Pop(): Integer - Remove an item at the top of stack

Pre-condition: isEmpty() == False

Post-condition: size() == n - 1, y = pop(), y == x

Error: isEmpty() == True, Stack Underflow

Return: return element removed if isEmpty()==false else null


Peek(): Integer - Return an item at the top of stack

Pre-condition: isEmpty(s) == False

Post-condition: y = peek(), y == x

Error: isEmpty() == True, Stack Underflow

Return: return element at the top if isEmpty()==false else null

 Queue

Queue q: named queue, n = size(): the length of queue, x = front(): value at the top of queue, z = rear():
value at the end of queue, capacity: max length of queue

isFull(): boolean - check queue is full or not

Pre-condition: None

Post-condition: size == capacity

Error: None

Return: return true if queue is full else false

isEmpty(): boolean - check queue is empty or not

Pre-condition: None

Post-condition: size() == 0

Error: None

Return: return true if queue is empty else false

Enqueue(item i): Boolean- Add new item at the rear of queue

Pre-condition: isFull() == False

Post-condition: size() == n + 1, z = i

Error: isFull() == True, Queue overflow

Return: return true if item i added else false


Dequeue(): Integer - Remove an item at the first

Pre-condition: IsEmpty() == False

Post-condition: size() == n -1, y = dequeue(), y == x

Error: IsEmpty()==True, Queue underflow

Return: Return element removed if isEmpty() == False else return null

Front(): Integer - Return element at first of queue

Pre-condition: IsEmpty() == False

Post-condition: y = front(), y==x

Error: IsEmpty()==True, Queue underflow

Return: Return element at first if isEmpty() == False else return null

Rear(): Integer - return element at last of queue

Pre-condition: IsEmpty() == False

Post-condition: y = rear(), y==z

Error: IsEmpty()==True, Queue underflow

Return: Return element at last if isEmpty() == False else return null

2. Explanation of the advantages of encapsulation and information hiding when using an ADT (M3)

2.1 Encapsulation

According to Craig (1996), Data encapsulation, sometimes referred to as data hiding, is the mechanism
whereby the implementation details of a class are kept hidden from the user. The user can only perform
a restricted set of operations on the hidden members of the class by executing special functions
commonly called methods. The actions performed by the methods are determined by the designer of the
class, who must be careful not to make the methods either overly flexible or too restrictive. This idea of
hiding the details away from the user and providing a restricted, clearly defined interface is the
underlying theme behind the concept of an abstract data type.

2.2 Why we need encapsulation?

According to Singh (2020), usages when use encapsulation:

﹣ Flexibility: It’s more flexible and easy to change the encapsulated code with new set of requirements.
For example, if the requirement for adding/removing the project of a employee changes, we can
easily update the logic in the setter method () or provided methods.

﹣ Re-usability: Encapsulated code can be reused throughout the application or across multiple
applications.

﹣ Maintainability: When application code is encapsulated in separate units (classes, interfaces,


methods, getters/setters etc) so it’s easy to change or update a part of the application without
affecting other parts, thus reducing the effort and time of the developer.

﹣ Test-ability: For an encapsulated class writing unit tests are easier as the member variables are not
scattered all around, thus reducing the time and effort of the tester as well.

﹣ Data Hiding: The caller of the methods will have no idea about the internal logic of the class as the
member variables are not visible to the caller function. Caller only knows the parameters which are to
be passed to the setter method (or any method) for getting initialized with that value.

2.3 Advantages and information hiding when using an ADT Encapsulation uses accessors and mutators
Encapsulation using properties

Actually, the advantages of encapsulation is when in class has changes but the interface remains the
same. For example, to create a stack class which can contain integers, the designer may choose to
implement it with an array, which is hidden from the user of the class. The designer then writes the
push() and pop() methods which puts integers into the array and removes them from the array
respectively. These methods are made accessible to the user. Should an attempt be made by the user to
access the array directly, a compile time error will result. Now, should the designer decide to change the
stack's implementation to a linked list, the array can simply be replaced with a linked list and the push()
and pop() methods rewritten so that they manipulate the linked list instead of the array. The code which
the user has written to manipulate the stack is still valid because it was not given direct access to the
array to begin with.
Figure 18: Implementation stack using array

So why we need accessor (like getter in OOP) and mutator (like setter in OOP) in data encapsulation. As
we known, in encapsulation information and data are hidden to be more safe and reduce complexity of
program. Even, in fact some methods are only read or write because they are private. So we need to use
accessor and mutator to access and edit the value of data. Therefore, class must provide that service
(accessor and mutator).

Some advantages:

﹣ For accessor, it will not change the object’s current statue, any data member do not change value
when we use it.

﹣ For mutator, it can be used to make sure that data elements are validated. This method is used to
check input values before assigning attributes.

﹣ Sometimes, we must change data or interface… this change will not affect to users, only developer
can see.

﹣ Encapsulation is the behavior associated to getter and setter, this function will help in add more
features in the future.
3. Discussion of imperative ADTs with regard to object orientation (D2)

Before going to compare ADTs and OOP is the same or difference. I will give quotes from well-known
authors about OOP to show more clearly.

According to Doherty (2015), Object-oriented programming (OOP) is a fundamental programming


module used by nearly every developer. OOP is the most popular programming and is the standard way
to code for most of a developer. OOP relies on the concept of classes and objects. It is used to structure
a software program into more simple and we can re-use it many times (classes) and they can be used to
create individual instances of objects.

In OOP programming, there are 4 principles:

Inheritance: this principles allow child classes inherit data and behaviors from parent class. Put another
way, parent classes extend attributes and behaviors to child classes. Inheritance supports re-usability. If
basic attributes and behaviors are defined in a parent class, child classes can be created extending the
functionality of the parent class, and adding additional attributes and behaviors.

Encapsulation: this principle is very important in programming. Encapsulation means containing all
important information inside an object, it helps developer can hide sensitive information and show
features for users only. When an object is instantiated from the class, the data and methods are
encapsulated in that object. Encapsulation hides the internal software code implementation inside a
class, and hides internal data of inside objects.

Abstraction: Abstraction means that the user interacts with only selected attributes and methods of an
object. It uses simplified, high-level tools, to access a complex object. More, abstraction is using simple
classes to represent complexity. In some case, we can say that abstraction is an extension of
encapsulation. For example, you don’t have to know all the details of how the engine works to drive a car.

Polymorphism: Polymorphism means designing objects to share behaviors. Using inheritance, objects
can override shared parent behaviors, with specific child behaviors. Polymorphism allows the same
method to execute different behaviors in two ways: method overriding and method overloading.
According to Cook (1990), abstract data types are organized around the data and operations. ADTs can
be viewed as a decomposition of specification matrix into observations. This slices the table horizontally
into a stack of rows, where each row collects the information about a single observer together in a unit.
Information about a given constructor is spread across components. Each observation is formed into an
independent operation that returns the appropriate result when applied to any of the constructors’
values. The constructors are also included as operations. The connection between the constructors and
the observations is via a shared representation. In order to keep the representation abstract, its
structure is hidden from clients of the ADT. In his conclusion, he stated that The essence of object-
oriented programming is procedural data abstraction, in which procedures are used to represent data
and procedural interfaces provide information hiding and abstraction. This technique is complementary
to ADTs, in which concrete algebras are used to represent data, and type abstraction provides
information hiding. The two paradigms can be derived from a fundamental dichotomy in decomposing a
matrix of observers and constructors that specify abstract data. PDA decomposes this matrix into
constructors: a class is associated with each constructor and the observations become attributes, or
methods, of the class’s instances. In effect, the values in the abstraction are nothing more or less than
the collection of legal observations on them.

After define OOP and ADTs. I’m going to define my conclusion that ADT allows the creation of instances
with well-defined properties and behavior. Abstraction allows collecting instances of entities into groups
in which their common attributes need to be considered. ADT based on data and operation. ADT is the
set of operations. ADT's are mathematical abstractions. Implementation independent data description
that specifies the contents, structure and legal operations on the data. Otherwise, OOP worked on basic
principles as encapsulation to store status and hide important information.

In summary, I state that ATDs is not an object-oriented concept at all, but a concept based on parametric
polymorphism. So ADTs and OOP are different from data abstraction.
Evaluation (D2)

Through this report, in part 1 I defined important data structures as Stack, Queue and Graph. I also gave
usage of each data structures and explanation them how to apply them on a project. To make them
more clearly I showed images, pseudo code, flowchart and steps implementations in detail. I then also
presented algorithm complexity based on time complexity and space complexity and when should we
use them. In part 2, at first I used an imperative definition, specify the abstract data type for a software
stack. After that, I also described advantages of encapsulation and information hiding when using an ADT
by giving examples and show theories of them. And finally I gave my opinions in discussing of imperative
ADTs with regard to object orientation by giving evidence.

Critical evaluate: understand, implement, use

After doing this report, I got more knowledge about data structure and their important in coding. For
each problem, we will have different data structures to make it easier. And after choosing a suitable data
structure, we need to choose an algorithm that is suitable and faster. In the educational environment,
we can exchange space complexity instead of time complexity… For example, in sorting we have many
algorithms. For an array has all positive numbers and we can control max, min value in not too big range
we can applied counting sort. But for a big data input, we should use quick sort or merge sort. Otherwise,
if we need to keep stability for problem, we can use bubble sort (not big data input). Or in data structure
graph, before I don’t know how Google Maps accessing inside or Facebook’s connection stored
relationship friend to make recommendation or more simple is find the shortest path. After learning
graph, I got my knowledge more clearly in this problem. Two algorithms I applied above are BFS and
Dijkstra. For each algorithm will have different, BFS is used to find the shortest path from two point that
does not have weight number (like distance and time is the same). But Dijkstra is used to find all the
shortest path from one point and in Dijkstra has weight number (distance or time…).

In part 2, I learned too much in OOP programming. I understood it more detail about it’s usage. Apart
from, the main part is I learned more about a new data type that isn't primitive. It’s called Abstract data
type. Implement an ADT is very important and necessary in programming. It helps us work more
intelligent and reduce complexity in coding. I also showed the same and difference of ADT and OOP in
programming.

In summary, after learning and do this report. I got my knowledge too more new data structures and
algorithms. Defines ADT and distinguishes similarities and differences between OOP vs ADT.

References

[1] Chauhan, A., 2019. Abstract Data Types - GeeksforGeeks. [online] GeeksforGeeks.

Available at: <https://www.geeksforgeeks.org/abstract-data-types/>

[Accessed 25 April 2021].

[2] Wuyn, L., 2021. Data Structure and Algorithms - Queue - Tutorialspoint. [online] Tutorialspoint.com.

Available at: <https://www.tutorialspoint.com/data_structures_algorithms/>

[Accessed 25 April 2021].

[3] Blake, T., 2021. Stack Data Structure and Implementation in Python, Java and C/C++. [online]
Programiz.com.

Available at: <https://www.programiz.com/dsa/>

[Accessed 25 April 2021].

[4] Griffin, L., 2019. [online] Study.com.

Available at: <https://study.com/academy/lesson/>

[Accessed 25 April 2021].

[5] Sedgewick, R. and Wayne, K., 2011. Algorithms, Fourth Edition. Princeton: Princeton University.

[6] Arikia, K., 2018. Graph Data Structure And Algorithms - GeeksforGeeks. [online] GeeksforGeeks.

Available at: <https://www.geeksforgeeks.org/graph-data-structure-and-algorithms/>

[Accessed 25 April 2021].


[7] Craig, D., 1996. Data Encapsulation. [online].

Available at: <http://www.cs.mun.ca/>

[Accessed 25 April 2021].

[8] Doherty, E., 2020. What is Object Oriented Programming? OOP Explained in Depth. [online]

Available at: <https://www.educative.io/>

[Accessed 25 April 2021].

[9] R.Cook, W., 1990. [online] OOP vs ADT.

Available at: <https://www.cs.utexas.edu/>

[Accessed 25 April 2021].

[10] Singh, V., 2020. Why should Encapsulation to be used?. [online] Medium.

Available at: <https://medium.com/javarevisited/>

[Accessed 25 April 2021].

You might also like