DSA Assignment

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 74

Higher Nationals

Internal verification of assessment decisions – BTEC (RQF)

INTERNAL VERIFICATION – ASSESSMENT DECISIONS


Programme title Higher National Diploma in Computing

Assessor Internal Verifier


Unit 19 – Data Structures and Algorithms
Unit(s)
Specification, Implementation, and Assessment of Data Structures for a sample
Assignment title scenario.

M.G.D.S.Hiruwinda
Student’s name
List which assessment criteria Pass Merit Distinction
the Assessor has awarded.

INTERNAL VERIFIER CHECKLIST

Do the assessment criteria awarded match


those shown in the assignment brief?
Y/N
Is the Pass/Merit/Distinction grade awarded
justified by the assessor’s comments on the
Y/N
student work?

Has the work been assessed


accurately? Y/N

Is the feedback to the student:


Give details:
• Constructive?
• Linked to relevant assessment criteria?
Y/N
• Identifying opportunities for
Y/N
improved performance?
Y/N
• Agreeing actions?
Y/N
Does the assessment decision need
amending? Y/N

Assessor signature Date

Internal Verifier signature Date


Programme Leader signature (if required)
Date
Confirm action completed
Remedial action taken

Give details:

Assessor signature Date


Internal Verifier
signature Date

Programme Leader
signature (if required) Date

Higher Nationals - Summative Assignment Feedback Form


Student Name/ID KUR00133075
Unit 19: Data Structures and Algorithms
Unit Title
Assignment Number 1 Assessor
Date Received 1st
Submission Date submission
Date Received 2nd
Re-submission Date
III
submission
Assessor Feedback:
LO1 Examine different concrete data structures and it’s valid operations.
Pass, Merit & P1 P2 M1 M2 D1
Distinction Descripts

LO2 Discuss the advantages, complexity of Abstract Data Type and importance concepts of
Object orientation.

Pass, Merit & P3 M3 D2


Distinction Descripts

LO3 Implement, Demonstrate and evaluate complex ADT algorithm.

Pass, Merit & P4 P5 M4 D3


Distinction Descripts

LO4 Examine the advantages of Independent data structures and discuss the need of
asymptotic analysis to assess the effectiveness of an algorithm.
Pass, Merit & P6 P7 M5 D4
Distinction Descripts

Grade: Assessor Signature: Date:


Resubmission Feedback:

Grade: Assessor Signature: Date:


Internal Verifier’s Comments:
Signature & Date:
* Please note that grade decisions are provisional. They are only confirmed once internal and external moderation has taken
place and grades decisions have been agreed at the assessment board.

Assignment Feedback
Formative Feedback: Assessor to Student

Action Plan

IV
Summative feedback

Feedback: Student to Assessor

Assessor Date
signature
hiruwindasahan@gmail.co
Student m Date
signature

Pearson Higher Nationals in


Computing
Unit 19: Data Structures & Algorithms
Assignment 01

V
General Guidelines

• A Cover page or title page – You should always attach a title page to your assignment.
Use previous page as your cover sheet and make sure all the details are accurately filled.

• Attach this brief as the first section of your assignment.

• All the assignments should be prepared using a word processing software.

• All the assignments should be printed on A4 sized papers. Use single side printing.

• Allow 1” for top, bottom , right margins and 1.25” for the left margin of each page.

Word Processing Rules

• The font size should be 12 point, and should be in the style of Time New Roman.

• Use 1.5 line spacing. Left justify all paragraphs.

• Ensure that all the headings are consistent in terms of the font size and font style.

• Use footer function in the word processor to insert Your Name, Subject, Assignment
No, and Page Number on each page. This is useful if individual sheets become detached
for any reason.

• Use word processing application spell check and grammar check function to help editing
your assignment.

Important Points:

• It is strictly prohibited to use textboxes to add texts in the assignments, except for the
compulsory information. eg: Figures, tables of comparison etc. Adding text boxes in the
body except for the before mentioned compulsory information will result in rejection of
your work.

• Carefully check the hand in date and the instructions given in the assignment. Late
submissions will not be accepted.
VI
• Ensure that you give yourself enough time to complete the assignment by the due date.

• Excuses of any nature will not be accepted for failure to hand in the work on time.

• You must take responsibility for managing your own time effectively.

• If you are unable to hand in your assignment on time and have valid reasons such as
illness, you may apply (in writing) for an extension.

• Failure to achieve at least PASS criteria will result in a REFERRAL grade .

• Non-submission of work without valid reasons will lead to an automatic RE FERRAL. You
will then be asked to complete an alternative assignment.

• If you use other people’s work or ideas in your assignment, reference them properly
using HARVARD referencing system to avoid plagiarism. You have to provide both in-
text citation and a reference list.

• If you are proven to be guilty of plagiarism or any academic misconduct, your grade
could be reduced to A REFERRAL or at worst you could be expelled from the course

Student Declaration

I hereby, declare that I know what plagiarism entails, namely to use another’s work and to
present it as my own without attributing the sources in the correct form. I further understand
what it means to copy another’s work.

• I know that plagiarism is a punishable offence because it constitutes theft.


VII
• I understand the plagiarism and copying policy of Edexcel UK.
• I know what the consequences will be if I plagiarise or copy another’s work in any of the
assignments for this program.
• I declare therefore that all work presented by me for every aspect of my program, will
be my own, and where I have made use of another’s work, I will attribute the source in
the correct way.
• I acknowledge that the attachment of this document signed or not, constitutes a binding
agreement between myself and Pearson, UK.
• I understand that my assignment will not be considered as submitted if this document is
not attached to the assignment.

Student’s Signature: Date:


(Provide E-mail ID) (Provide Submission Date)

Higher National Diploma in Business


Assignment Brief
Student Name /ID Number KUR00133075
Unit Number and Title Unit 19 : Data Structures and Algorithms
Academic Year 2021/22
Unit Tutor
Assignment Title Specification, Implementation, and Assessment of Data Structures
for a sample scenario.
Issue Date
Submission Date 4/28/2023
IV Name & Date

Submission format

The submission should be in the form of a report, which contains code snippets
(which must be described well), text-based descriptions, and diagrams where
appropriate. References to external sources of knowledge must be cited (reference

VIII
list supported by in-text citations) using the Harvard Referencing style.

Unit Learning Outcomes:

LO1. Examine abstract data types, concrete data structures and algorithms.
LO2. Specify abstract data types and algorithms in a formal notation.
LO3. Implement complex data structures and algorithms.
LO4. Assess the effectiveness of data structures and algorithms.

Assignment Brief and Guidance:


Scenario
ABC Pvt Ltd organizing Car Racing event across western province and they decided to
have maximum of 6 cars(participants) to compete.
There are totally 3 Rounds and at the end of each round lowest rank car will be
eliminated from the Race.
Each car has unique number, brand, sponsor and driver details.

In order to manage this particular event ABC Pvt Ltd decided to develop an
Application.
Application functions are listed down.

1.Register Car Details


2.Delete a car

IX
3.Insert 3 Rounds Results.
4.Find out the winners (1st,2nd,3rd)
5.Search for a particular car

Task 1: Examine and create data structure by simulating the above scenario and
explain the valid operations that can be carried out on this data structure.
Determine the operations of a queue and critically review how it is used to
implement function calls related to the above scenario.

Task 2: Implement the above scenario using the selected data structure and its valid
operations for the design specification given in task 1 by using java programming.
Use suitable error handling and Test the application using suitable test cases and
illustrate the system. Provide evidence of the test cases and the test results.

Task 3 : Registered Car details are stored from oldest to newest. Management of
ABC Pvt Ltd should be able to find from the newest to oldest registered car details.
Using an imperative definition, specify the abstract data type for the above scenario
and implement specified ADT using java programming and briefly discuss the
complexity of chosen ADT algorithm. List down the advantages of Encapsulation and
Information hiding when using an ADT selected for the above scenario.
“Imperative ADTs are basis for object orientation.” Discuss the above view stating
whether you agree or not. Justify your answer.

Task 4: ABC Pvt Ltd plans to visit all of these participants through the shortest path
within a day.
Analyse the above operation by using illustrations, of two shortest path algorithms,
specify how it operates using a sample graph diagram. Sort the cars based on
numbers with two different sorting algorithms and critically review the
performances of those two algorithms by comparing them.

X
Task 5: Evaluate how Asymptotic analysis can be used to assess the effectiveness of
an algorithm and critically evaluate the different ways in which the efficiency of an
algorithm can be measured.
Critically review the sort of trade-offs exists when you use an ADT for implementing
programs. You also need to evaluate the benefits of using independent data
structures for implementing programs.

Grading Rubric

Grading Criteria Achieved Feedback

LO1. Examine abstract data types,


concrete data structures and algorithms.

P1 Create a design specification for data


structures explaining the valid operations
that can be carried out on the structures.

P2 Determine the operations of a memory


stack and how it is used to implement
function calls in a computer.

XI
M1 Illustrate, with an example, a concrete
data structure for a First In First out (FIFO)
queue.

M2 Compare the performance of two


sorting algorithms.
D1 Analyse the operation, using
illustrations, of two network shortest path
algorithms, providing an example of each.

LO2. Specify abstract data types and


algorithms in a formal notation.

P3 Using an imperative definition,


specify the abstract data type for a
software stack.

M3 Examine the advantages of


encapsulation and
information hiding when using an
ADT.

D2 Discuss the view that imperative ADTs


are a basis for object orientation and,
with justification, state whether you
agree.

LO3. Implement complex data structures


and algorithms.

P4 Implement a complex ADT and


algorithm in an executable programming
language to solve a well-defined problem.

P5 Implement error handling and report

XII
test results.

M4 Demonstrate how the


implementation of an ADT/algorithm
solves a well-defined problem.
D3 Critically evaluate the complexity of an
implemented ADT/algorithm.
LO4. Assess the effectiveness of data
structures and algorithms.
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.

M5 Interpret what a trade-off is when


specifying an ADT using an example to
support your answer.

D4 Evaluate three benefits of using


implementation independent data
structures.

XIII
Table of Contents
Task 01.......................................................................................................................................
1.1 Examine abstract data types, concrete data structures and algorithms.......................1
1.1.1 Data Structures........................................................................................................1
1.1.2. Why data structures important?..............................................................................2
1.1.3 How are Data structures used?................................................................................2
1.1.4 Types of Data structures..........................................................................................4
Algorithm for Linked list.................................................................................................5
1.2 Concrete data structures and algorithms................................................................7
1.3 Determine the operations of a memory stack........................................................9
Task 02.....................................................................................................................................
The Java code for the "Car" class with the specified attributes...............................................
1. Define an array of type "Car" with a fixed size of 6 to store the car details...........13
The Use Of Try-Catch Blocks To Handle Any Errors.............................................................
Test cases to ensure that the application works as expected..........................................21
The implementation of the solution in Java programming language.......................................
Task 03.....................................................................................................................................
Abstract Data Type (ADT) I. Abstract Data Type (ADT).......................................................
Complexity Analysis of the Chosen ADT Algorithm..............................................................
Task 04.....................................................................................................................................
4.1 Assess the effectiveness of data structures and algorithms......................................35
4.1.1 Compare the performance of two sorting algorithms....................................................35
4.2 Analyze the operation, using illustrations, of two network shortest path algorithms,
providing an example of each........................................................................................39
Task 05.....................................................................................................................................
5.1 Discuss how asymptotic analysis can be used to assess the effectiveness of an
algorithm........................................................................................................................51
5.1.1 What is Algorithm Analysis?................................................................................51
5.1.2 Why is Algorithm Analysis Important?................................................................51
5.1.3 Experimental and Asymptotic Analysis................................................................52
5.2 Types of Asymptotic Notations in Complexity Analysis of Algorithms.................52
Theta Notation (Θ-Notation):.........................................................................................52
5.2.1 How to measure the efficiency of algorithms.......................................................55
1

M.G.Dineru Sahan Hiruwinda E163365 DSA


5.3 Time complexity represents the number of times a statement is executed..............56
5.3.1 Interpret a trade-off specifying an ADT................................................................57
5.4 Benefits of using implementation independent data structures................................58
References:...............................................................................................................................

M.G.Dineru Sahan Hiruwinda E163365 DSA


Task 01
1.1 Examine abstract data types, concrete data structures and algorithms.

1.1.1 Data Structures

An expertly designed format for arranging, processing, accessing, and storing data is
called a data structure. Data structures come in both simple and complex forms, all of
which are made to organize data for a certain use. Users find it simple to access the data
they need and use it appropriately thanks to data structures. The organizing of information
is framed by data structures in a way that both machines and people can better grasp.

A data structure may be chosen or created in computer science and computer


programming to store data to be used with different methods. In some circumstances, the
design of the data structure and the algorithm's fundamental operations are closely
related. Each data structure includes details about the values of the data, the connections
between the data, and, occasionally, functions that can be used to manipulate the data.

For instance, the data structure and the accompanying methods are tied together as part of
the class definition in an object-oriented programming language. Although they may be
designed to operate with the data structure in non-object-oriented languages, these
functions are not considered to be a part of the data structure.

3 Data Structures
Figure 1:

M.G.Dineru Sahan Hiruwinda E163365 DSA


1.1.2. Why data structures important?

When it comes to communicating the logical meaning behind data processing and
application, the typical fundamental data types present in most computer programming
languages, such as integers or floating-point numbers, are frequently insufficient.
Applications that ingest, manipulate, and output information must understand how data
should be arranged in order to make processing easier. Data structures logically combine
various data components to enable effective data consumption, persistence, and exchange.
They offer a formal model that specifies how the data elements should be arranged.

For more complicated applications, data structures serve as the foundation. They are
produced by combining data elements into coherent units that reflect abstract data types
pertinent to the algorithm or application under development. "Customer name" is an
illustration of an abstract data type. It is made up of character strings that stand in for the
"first name," "middle name," and "last name."

1.1.3 How are Data structures used?

To construct the physical representations of abstract data types, data structures are
frequently utilized. Data structures must be carefully considered when developing
software. They are essential to the development of algorithms and their use in real-world
computer programs.

Usually, data structures are used to create the physical representations of abstract data
types. Using the right data structures is necessary for developing efficient applications.
They are essential for both designing algorithms and putting them to use in computer
applications.The data structures that software developers use, such as lists, queues, and
mappings that pair up different sets of values, are strongly related to the algorithms they
use. The management of record collections in a relational database and the creation of an
index of those records using the binary tree data structure are two applications where this
method is useful.

M.G.Dineru Sahan Hiruwinda E163365 DSA


Data Storage: Data structures are used to provide effective and lasting data storage when
designing the properties and structures for storing records in a database management
system.

Resource and service administration: The efficient administration of fundamental


operating system resources and functions is made possible by the use of data structures
like linked lists for tasks like memory allocation, file directory management, file structure
trees, and process scheduling queues.
Data Exchange: To organize and manage information shared across programs, such as
TCP/IP packets in networking, data structures are utilized, which enables effective data
exchange.

Ordering and Sorting: Data structures like priority queues and binary search trees offer
effective ways for ordering and sorting data components, such as character strings used as
tags, enabling programmers to manage the priority of objects.

Indexing: In databases, complex data structures like B-trees are used to index things,
improving the effectiveness of search operations and retrieval.

Searching: To create indexes that speed up the process of finding specific objects within a
dataset, methods like B-trees, hash tables, and binary search trees are frequently
employed.

Scalability: To allocate and manage data storage across distributed storage sites while
ensuring performance and scalability, data structures are essential in big data applications.
Data structures that duplicate the underlying structure of database records are offered by
programming environments like Apache Spark, making querying simpler.

Overall, data structures are crucial for many areas of data management because they make
it possible for information to be stored, processed, and retrieved in a variety of
applications and systems in an efficient manner.

 
5

M.G.Dineru Sahan Hiruwinda E163365 DSA


1.1.4 Types of Data structures

The precise operations or algorithms necessary in a given circumstance dictate the sort of
data structure to be used. Various data structure types are listed below:

An array keeps a group of things in close proximity to one another in memory. Items of
the same type are gathered together to facilitate simple index-based retrieval. Array
lengths can be either fixed or variable.
Stack: Depending on the chosen layout, a stack arranges objects in a linear series that
follows the "first in, first out" (FIFO) or "last in, first out" (LIFO) order.

Queue: A queue stores a group of items similarly to a stack, but all actions are always
carried out according to the principle of "first in, first out."

Linked list: A linked list keeps track of the items in a logical order. The linked list's
elements and nodes each contain data items and references to the subsequent items.

Tree: A tree organizes a group of things into an arbitrary hierarchy. Each node has a
unique key value, and parent nodes and child nodes (subnodes) are connected. All nodes
in the tree have their roots as their common ancestor.

Heap: In a heap, each parent node's key value is higher than or on par with that of its
offspring. Tree-based data structures are heaps.

 Graph: A graph is a nonlinear way to store a group of elements. There are a finite
number of nodes (vertices) and lines (edges) that make up the structure. Graphs can be
used to model real systems, including computer networks.

Trie: A trie, commonly referred to as a keyword tree, organizes strings into a visible
graph-like structure and stores them as data objects.

Hash table: Also known as a hash map, a hash table is a type of data structure that is used
to store a variety of things in an associative array that maps keys to values. An index is
6

M.G.Dineru Sahan Hiruwinda E163365 DSA


converted into an array of buckets containing the required data item using a hash
function.

The operations and algorithms necessary for a certain situation determine the data
structure to be used.

Algorithm for Linked list


Step 1: If the available space (AVAIL) is empty,

Display "OVERFLOW"

Proceed to Step 7

[End of Condition]

Step 2: Assign the new node as NEW_NODE

Step 3: Update AVAIL to the next available space

Step 4: Set the data of NEW_NODE as VAL

Step 5: Set the next pointer of NEW_NODE to HEAD

Step 6: Update HEAD to point to NEW_NODE

Step 7: Exit the algorithm

Pseudocode for Linked list


Declare a class called Node

Declare a string variable called name

Declare a Node variable called next

Set the initial value of top as NULL

M.G.Dineru Sahan Hiruwinda E163365 DSA


Creating a singly linked
Initialize the top node as a new node.

Set the name attribute of the top node to "A".

Set the next attribute of the top node to NULL.

insertion before the first node in a singly linked list:


Declare a temporary node called "temp".
Create a new node and assign it to "temp".
Set the name attribute of "temp" to "B".
Set the next attribute of "temp" to the current top node.
Update the top node to be "temp".
Algorithm for Stack (Push operation):

The algorithm is used to push an item into the stack.


If the top of the stack is equal to the maximum size, print "Stack is full" and exit.
Otherwise, increment the top by 1, assign the item to the stack at the updated top position.
Exit the algorithm.

Pseudocode for Stack:


Declare a constant called MAX_SIZE and set it to 100.
Create an array called "stack" with a size of MAX_SIZE.
Set the top variable to -1.
Define a function called "is_full" that takes the top as a parameter.
If the top is equal to MAX_SIZE - 1, return True; otherwise, return False.
Define a function called "push" that takes the stack, top, and data as parameters.
If the stack is full (using the "is_full" function), print "Stack is full".

M.G.Dineru Sahan Hiruwinda E163365 DSA


Otherwise, increment the top by 1 and assign the data to the stack at the updated top
position.
Return the updated top.

1.2 Concrete data structures and algorithms

Specific forms of data structures with specified implementations in programming


languages are referred to as "concrete data structures" and "concrete algorithms." These
structures are made to manipulate and store data effectively. Arrays, linked lists, stacks,
queues, trees, and graphs are a few examples of tangible data structures.
Algorithms, on the other hand, are collections of guidelines or processes that computer
programs adhere to in order to solve issues. They are necessary for efficiently processing
and modifying data structures. Searching algorithms like linear search and binary search,
sorting algorithms like bubble sort and merge sort, and graph traversal techniques are a
few examples of algorithms.

It is essential to choose the right data structures and algorithms for the task at hand when
creating software applications. The effectiveness of an application can be considerably
impacted by the choice of data structure and algorithm. Making decisions based on the
particular needs of the application demands a thorough understanding of concrete data
structures and algorithms.

First in First out method

The idea that the first assets purchased or generated should be sold, utilized, or disposed
of first is the guiding idea behind the First In, First Out (FIFO) method, a technique used
to manage and evaluate assets.

The FIFO technique makes the fiscal assumption that the costs associated with the oldest
inventory items are included in the cost of goods sold (COGS) on the income statement. It
contrasts the remaining inventory items with those that were just purchased or created.

M.G.Dineru Sahan Hiruwinda E163365 DSA


Basic Operations

Initializing a queue, using it, and permanently deleting the data from memory are all
considered basic operations. The queue abstract data type (ADT) depends on these
operations.
Enqueue(), dequeue(), peek(), isFull(), and isEmpty() are the queue ADT's five most
important operations. These built-in operations allow for data processing while
determining the queue's status.
The queue makes use of front and rear pointers to aid enqueuing. While the front pointer
accesses data from the front end of the queue, the rear pointer accesses data from the back
end. The right order of data insertion and retrieval is maintained with the help of this
method.

enqueue ()

Using two data pointers at the front and back of the queue, the enqueue() process includes
adding data to the queue. Compared to stack operations, enqueue operations can be more
difficult to implement. The procedure for putting data into a queue is outlined in the steps
below:

First, see if the line is long enough.


Step 2: Produce an overflow error and stop the procedure if the queue is full.Step 3:
Advance the back pointer to the next open spot if the queue is not full.
Step 4: Add the data element to the queue at the back pointer's suggested location.
Return a success status in step 5 to show that the enqueue operation was successful.

Dequeue

The dequeue procedure comprises accessing the data pointed to by the front pointer and
then removing the accessed data to get data from a queue in two phases. To execute a
dequeue action, adhere to the instructions below:

10

M.G.Dineru Sahan Hiruwinda E163365 DSA


First, see if there is no queue.
Step 2: Produce an underflow error and stop the process if the queue is empty.
Step 3: Access the information pointed to by the front pointer if the queue is not empty.
Step 4: Navigate to the following accessible data element with the front pointer.
Step 5: Confirm that the operation was successfully completed.

1.3 Determine the operations of a memory stack.

Data is arranged and kept in linear data structures called memory stacks or lines in
computer memory. Stacks work in a certain order and are intended to hold data of the
same type. The most recent item added is the first one to be withdrawn since they use the
Last-In, First-Out (LIFO) mechanism. The stack functions according to a set of
established insertion and removal methods,which guarantee that the data is accessed and
managed in a methodical way. The various stack manipulation operations will be covered
in this section.

Last in first out

The management and access of data in a stack are governed by the "last-in, first-out"
(LIFO) concept. With LIFO, the computer handles data requests within its memory in a
certain way. This principle states that the data that was added or placed in the stack most
recently is the first to be erased. It is significant to notice that applying LIFO to a movie
queue would result in anarchy, as seen in the previous figure. We shall examine the
actions carried out on a stack using the figure shown below in the sections that follow.

1) The push operation

Adding data items to a stack is the main goal of the push operation. In our second
example of the restaurant plate dispenser, adding plates (or data items) to the dispenser
(stack) is the push operation. The first plate is moved to the bottom of the stack and is
followed by each additional plate. The first new piece of data is placed at the bottom of
the arrangement, making it the least visible.

11

M.G.Dineru Sahan Hiruwinda E163365 DSA


2) The pop operation

A populated stack of data objects can be cleared out using the pop function. In the
analogy of the plate dispenser, the most current plate (piece of data) is placed on top of
the stack. This top-most data item will be the first thing eliminated when using the pop
operation. By thinking about the spring loading system at the plate dispenser's base, you
may picture this procedure. Every time a plate is removed, the stack of plates rises, which
causes succeeding items to appear in the same sequence in the memory.

3) The peek operations

We then do the push and pop operations before completing the stacks' peek operation. A
"peek" is a brief observation or examination of anything that is present in a specific
region. It entails searching for a certain piece within a stack at a particular location.
Before adding an element to the top of a stack, make sure it isn't already full by
increasing the value. Make sure the stack is not empty before peeking at it. You can
access the top element without changing its value if it's not empty.

4) The search operations

A letter or string used to limit the results of a search is referred to as a search operator or
search parameter. In computer science and mathematics, operators carry out operations.
Boolean operators like AND, NOT, and OR, which are frequently employed in search
operations, have particular purposes. AND demands that the search results contain both
the words or phrases that come before and after it. NOT filter out particular words or
phrases from the outcomes. OR incorporates both terms as well as any others. Before a
query word or phrase, other search operators are used. Multiple operators can be
combined to further refine the search emphasis.

Function Calls and the Call Stack

In contrast to the fundamental machine model we previously described, stack-based


memory management takes a more organized approach to memory management. Stack-

12

M.G.Dineru Sahan Hiruwinda E163365 DSA


based memory management employs activation records to store data for function calls
rather than allocating specific regions of memory to each object.
In addition to the function's parameters and local variables, an activation record also
includes additional relevant information like temporary objects and return addresses. Our
focus will mostly be on the parameters and local variables contained in the activation
record, even though the finer intricacies of these additional bits of data are outside the
purview of this course.

Activation records are arranged in a stack-like data structure in stack-based memory


management. Imagine a stack of pancakes when picturing this construction. A freshly
created pancake is added on top of the stack, and the top pancake is removed as one is
taken away. The most recent pancake made is the first one eaten in this arrangement,
which adheres to the last-in, first-out (LIFO) principle. The most recent activation record
made is the first one to be deleted and eliminated, and activation records are layered on
top of one another similarly.

Because the activation record of the most recently run function is at the top of the stack,
the stack-based approach makes sure that it receives precedence in memory. A dynamic
and effective memory management system is produced by adding and removing the
necessary activation records from the stack when functions are called and returned.
Function-related data can be stored and retrieved effectively using this strategy, giving
programs the structure they need to run.

Task 02.

The Java code for the "Car" class with the specified attributes
public class Car {
private int carNumber;
private String brand;

13

M.G.Dineru Sahan Hiruwinda E163365 DSA


private String sponsor;
private String driverDetails;

public Car(int carNumber, String brand, String sponsor, String driverDetails) {


this.carNumber = carNumber;
this.brand = brand;
this.sponsor = sponsor;
this.driverDetails = driverDetails;
}

public int getCarNumber() {


return carNumber;
}

public String getBrand() {


return brand;
}

public String getSponsor() {


return sponsor;
}

public String getDriverDetails() {


return driverDetails;
}
}

14

M.G.Dineru Sahan Hiruwinda E163365 DSA


The above class has a constructor that takes in the values for the car attributes and sets
them using the "this" keyword. It also has getter methods for each attribute so that they
can be accessed outside the class.

1. Define an array of type "Car" with a fixed size of 6 to store the car details.

Car[] carArray = new Car[6];

This creates an array of type "Car" with a fixed size of 6 and initializes all elements to
null. You can then store Car objects in the array by assigning them to the appropriate
index. For example, to store a Car object at index 0:

carArray[0] = new Car(1, "Toyota", "ABC Motors", "John Doe");

This creates a new Car object with the specified attributes and stores it in the first element
of the carArray.

2. Producing A class named "CarRace" that contains the following methods:

• registerCarDetails(): This method takes input from the user and registers the car
details by creating a new Car object and storing it in the array.

• deleteCar(): This method takes input from the user and deletes a car from the array
based on the car number.

• insertRoundResults(): This method takes input from the user and updates the
round results for each car in the array.

• findWinners(): This method finds the winners of the race based on the round
results and displays them to the user.

15

M.G.Dineru Sahan Hiruwinda E163365 DSA


• searchCar(): This method takes input from the user and searches for a particular
car in the array based on the car number.

The Java code for the "CarRace" class with the specified methods

import java.util.Scanner;

public class CarRace {

private Car[] carArray = new Car[6];

private int[] roundResults = new int[6];

private int numCars = 0;

public void registerCarDetails() {

Scanner input = new Scanner(System.in);

if (numCars == 6) {

System.out.println("Maximum number of cars reached!");

return;

System.out.print("Enter car number: ");

int carNumber = input.nextInt();


16

M.G.Dineru Sahan Hiruwinda E163365 DSA


input.nextLine();

System.out.print("Enter car brand: ");

String brand = input.nextLine();

System.out.print("Enter car sponsor: ");

String sponsor = input.nextLine();

System.out.print("Enter driver details: ");

String driverDetails = input.nextLine();

Car car = new Car(carNumber, brand, sponsor, driverDetails);

carArray[numCars] = car;

numCars++;

System.out.println("Car registered successfully!");

public void deleteCar() {

Scanner input = new Scanner(System.in);

if (numCars == 0) {

17

M.G.Dineru Sahan Hiruwinda E163365 DSA


System.out.println("No cars registered!");

return;

System.out.print("Enter car number to delete: ");

int carNumber = input.nextInt();

for (int i = 0; i < numCars; i++) {

if (carArray[i].getCarNumber() == carNumber) {

for (int j = i; j < numCars - 1; j++) {

carArray[j] = carArray[j+1];

roundResults[j] = roundResults[j+1];

carArray[numCars-1] = null;

roundResults[numCars-1] = 0;

numCars--;

System.out.println("Car deleted successfully!");

return;

System.out.println("Car not found!");

18

M.G.Dineru Sahan Hiruwinda E163365 DSA


}

public void insertRoundResults() {

Scanner input = new Scanner(System.in);

if (numCars == 0) {

System.out.println("No cars registered!");

return;

for (int i = 0; i < numCars; i++) {

System.out.print("Enter round " + (i+1) + " result for car " +


carArray[i].getCarNumber() + ": ");

roundResults[i] = input.nextInt();

System.out.println("Round results updated successfully!");

public void findWinners() {

if (numCars == 0) {

System.out.println("No cars registered!");

return;
19

M.G.Dineru Sahan Hiruwinda E163365 DSA


}

int[] sortedResults = roundResults.clone();

Arrays.sort(sortedResults);

System.out.println("Winners:");

for (int i = 0; i < 3; i++) {

int result = sortedResults[i];

for (int j = 0; j < numCars; j++) {

if (roundResults[j] == result) {

System.out.println((i+1) + ". " + carArray[j].getBrand() + " - " +


carArray[j].getDriverDetails());

break;

public void searchCar() {

Scanner input = new Scanner(System.in);

if (numCars == 0) {

System.out.println("No cars registered!");


20

M.G.Dineru Sahan Hiruwinda E163365 DSA


return;

System.out.print("Enter car number to search: ");

int carNumber = input.nextInt();

for (int

The Use Of Try-Catch Blocks To Handle Any Errors

We can use try-catch blocks to handle any errors that may occur during input or
processing as follows:

1. Place the code that may generate an exception inside a try block.

2. If an exception occurs during the execution of the code inside the try block, it is
caught by the catch block.

3. In the catch block, we can handle the exception by displaying an error message to
the user or taking appropriate action to recover from the exception.

4. If no exception occurs, the catch block is skipped and the program continues to
execute normally.

Scanner scanner = new Scanner(System.in);

try {

21

M.G.Dineru Sahan Hiruwinda E163365 DSA


System.out.print("Enter car number: ");
int carNumber = scanner.nextInt();

// Process car number input

} catch (InputMismatchException e) {
System.out.println("Invalid input. Please enter a valid integer for car number.");
}

Test cases to ensure that the application works as expected

1. Test registering car details:

• Register 6 cars with unique car numbers, brands, sponsors, and driver details.
Verify that the cars are added to the array and the correct details are stored.

2. Test deleting a car:

• Delete a car from the array by entering its car number. Verify that the car is
removed from the array and the remaining cars are shifted to fill the empty spot.

3. Test inserting round results:

• Enter round results for all 6 cars. Verify that the round results are stored correctly
for each car.

4. Test finding winners:

• Enter round results for all 6 cars and find the winners. Verify that the winners are
correctly identified based on the round results.

5. Test searching for a particular car:

22

M.G.Dineru Sahan Hiruwinda E163365 DSA


• Search for a car by entering its car number. Verify that the correct car details are
displayed.

6. Test deleting a car that does not exist:

• Try to delete a car that does not exist by entering an invalid car number. Verify
that an appropriate error message is displayed.

7. Test entering round results for a car that does not exist:

• Try to enter round results for a car that does not exist by entering an invalid car
number. Verify that an appropriate error message is displayed.

8. Test entering invalid round results:

• Try to enter invalid round results (e.g., negative or non-numeric values). Verify
that an appropriate error message is displayed.

9. Test registering more than 6 cars:

• Try to register more than 6 cars. Verify that an appropriate error message is
displayed and the extra cars are not added to the array.

The implementation of the solution in Java programming language

Car.java

public class Car {


private int carNumber;
private String brand;
private String sponsor;
private String driverDetails;

23

M.G.Dineru Sahan Hiruwinda E163365 DSA


private int[] roundResults;

public Car(int carNumber, String brand, String sponsor, String driverDetails) {


this.carNumber = carNumber;
this.brand = brand;
this.sponsor = sponsor;
this.driverDetails = driverDetails;
this.roundResults = new int[3];
}

public int getCarNumber() {


return carNumber;
}

public String getBrand() {


return brand;
}

public String getSponsor() {


return sponsor;
}

public String getDriverDetails() {


return driverDetails;
}

public void setRoundResults(int roundNumber, int result) {


this.roundResults[roundNumber - 1] = result;
24

M.G.Dineru Sahan Hiruwinda E163365 DSA


}

public int[] getRoundResults() {


return roundResults;
}

public int getTotalScore() {


int total = 0;
for (int i = 0; i < roundResults.length; i++) {
total += roundResults[i];
}
return total;
}

public String toString() {


return "Car Number: " + carNumber +
"\nBrand: " + brand +
"\nSponsor: " + sponsor +
"\nDriver Details: " + driverDetails;
}
}

CarRace.java

import java.util.Scanner;

public class CarRace {


private Car[] cars;
25

M.G.Dineru Sahan Hiruwinda E163365 DSA


public CarRace() {
this.cars = new Car[6];
}

public void registerCarDetails() {


Scanner input = new Scanner(System.in);

System.out.print("Enter car number: ");


int carNumber = input.nextInt();
input.nextLine();

System.out.print("Enter brand: ");


String brand = input.nextLine();

System.out.print("Enter sponsor: ");


String sponsor = input.nextLine();

System.out.print("Enter driver details: ");


String driverDetails = input.nextLine();

Car car = new Car(carNumber, brand, sponsor, driverDetails);

boolean carAdded = false;


for (int i = 0; i < cars.length; i++) {
if (cars[i] == null) {
cars[i] = car;
System.out.println("Car added successfully.");
26

M.G.Dineru Sahan Hiruwinda E163365 DSA


carAdded = true;
break;
}
}
if (!carAdded) {
System.out.println("Cannot add more cars. The limit is 6.");
}
}

public void deleteCar() {


Scanner input = new Scanner(System.in);

System.out.print("Enter car number to delete: ");


int carNumber = input.nextInt();

boolean carDeleted = false;


for (int i = 0; i < cars.length; i++) {
if (cars[i] != null && cars[i].getCarNumber() == carNumber) {
cars[i] = null;
System.out.println("Car deleted successfully.");
carDeleted = true;
break;
}
}
if (!carDeleted) {
System.out.println("Car not found.");
} else {
// shift remaining cars to fill empty spot
27

M.G.Dineru Sahan Hiruwinda E163365 DSA


for (int i = 0; i < cars.length - 1; i++) {
if (cars[i] == null) {
cars[i] = cars[i + 1];
cars[i + 1] = null;
}
}
}
}

public void insertRoundResults() {


Scanner input = new Scanner(System.in);

for (int

5. Provide evidence of the test cases and their results, including any screenshots or
output logs.

Task 03.

Abstract Data Type (ADT) I. Abstract Data Type (ADT)


A. Definition and purpose of ADT:

Abstract Data Type (ADT) is a high-level description of a set of data values and the
operations that can be performed on them. It provides an abstract view of a data structure
independent of its implementation. ADT is a useful tool in software development as it
helps in creating efficient algorithms, promotes code reuse, and simplifies code
maintenance.

B. Imperative definition of ADT for the scenario:

28

M.G.Dineru Sahan Hiruwinda E163365 DSA


The ADT for the scenario is a linked list, which is an ordered collection of Car objects.
The linked list will be implemented using nodes, where each node contains a Car object
and a reference to the next node in the list.

The operations that can be performed on the ADT are as follows:

1. addCar(Car car): Adds a Car object to the end of the linked list.

2. deleteCar(int carNumber): Deletes a Car object from the linked list based on the
car number.

3. getCar(int carNumber): Searches for and returns a Car object from the linked list
based on the car number.

4. displayAllCars(): Displays all Car objects in the linked list from the newest to
oldest registered.

C. Implementation of ADT using Java programming:

To implement the linked list ADT, we will create two classes: "Car" and
"LinkedListNode". The "LinkedListNode" class will contain a reference to a "Car" object
and a reference to the next "LinkedListNode". The "Car" class will contain attributes such
as carNumber, brand, sponsor, and driverDetails.

Next, we will create a "LinkedList" class that contains methods to perform the operations
listed in the imperative definition of the ADT. The "LinkedList" class will contain a
reference to the first "LinkedListNode" in the list.

The following is the Java code for implementing the ADT:

public class Car {


private int carNumber;
private String brand;
private String sponsor;
private String driverDetails;

29

M.G.Dineru Sahan Hiruwinda E163365 DSA


// Constructor
public Car(int carNumber, String brand, String sponsor, String driverDetails) {
this.carNumber = carNumber;
this.brand = brand;
this.sponsor = sponsor;
this.driverDetails = driverDetails;
}

// Getter methods for attributes


public int getCarNumber() {
return carNumber;
}

public String getBrand() {


return brand;
}

public String getSponsor() {


return sponsor;
}

public String getDriverDetails() {


return driverDetails;
}
}

public class LinkedListNode {


30

M.G.Dineru Sahan Hiruwinda E163365 DSA


private Car car;
private LinkedListNode next;

// Constructor
public LinkedListNode(Car car) {
this.car = car;
this.next = null;
}

// Getter and setter methods


public Car getCar() {
return car;
}

public void setNext(LinkedListNode next) {


this.next = next;
}

public LinkedListNode getNext() {


return next;
}
}

public class LinkedList {


private LinkedListNode head;

// Constructor
public LinkedList() {
31

M.G.Dineru Sahan Hiruwinda E163365 DSA


head = null;
}

// Method to add a Car object to the end of the linked list


public void addCar(Car car) {
LinkedListNode newNode = new LinkedListNode(car);

if (head == null) {
head = newNode;
} else {
LinkedListNode currentNode = head;
while (currentNode.getNext() != null) {
currentNode = currentNode.getNext();
}
currentNode.setNext(newNode);
}
}

// Method to delete a Car object from the linked list based on the car number
public void deleteCar(int

Complexity Analysis of the Chosen ADT Algorithm


Since the chosen ADT algorithm is a linked list, the time and space complexities depend
on the operations performed on the linked list.

A. Time complexity:
32

M.G.Dineru Sahan Hiruwinda E163365 DSA


1. Insertion: The time complexity for inserting a node at the beginning of the linked
list is O(1). Inserting a node at the end of the linked list takes O(n) time complexity where
n is the number of nodes in the linked list.

2. Deletion: The time complexity for deleting a node from the beginning of the
linked list is O(1). Deleting a node from the end of the linked list takes O(n) time
complexity where n is the number of nodes in the linked list.

3. Searching: The time complexity for searching a node in the linked list is O(n)
where n is the number of nodes in the linked list.

B. Space complexity: The space complexity of the linked list algorithm depends on the
number of nodes in the linked list. For each node, a fixed amount of memory is required
to store the node's data and a reference to the next node. Therefore, the space complexity
of the linked list is O(n) where n is the number of nodes in the linked list.

Overall, the time complexity for the operations performed on the linked list is efficient,
while the space complexity is directly proportional to the number of nodes in the linked
list.

Advantages of Encapsulation and Information Hiding when Using an


ADT
Encapsulation and information hiding are important concepts in object-oriented
programming, and they offer several advantages when using an ADT:

1. Modularity: Encapsulation allows for the implementation of an ADT to be hidden


from the user, providing a clear separation between the implementation and the interface.
This enhances the modularity of the program and allows for easier maintenance and
modification.

2. Data Protection: Encapsulation provides data protection by restricting access to


the internal state of an object. This prevents the user from modifying the internal state of
the object and ensures that the object remains in a consistent state.

33

M.G.Dineru Sahan Hiruwinda E163365 DSA


3. Abstraction: Encapsulation allows for the implementation of an ADT to be
abstracted away from the user. This means that the user does not need to know the details
of the implementation to use the ADT effectively.

4. Security: Encapsulation and information hiding can improve the security of a


program by limiting the exposure of internal implementation details to the user. This can
help prevent unauthorized access and manipulation of the program's data.

Advantages of Encapsulation and Information Hiding with ADT

Encapsulation and information hiding are two important concepts in object-oriented


programming that help to achieve data abstraction and protect data integrity.
Encapsulation refers to the process of bundling data and methods into a single unit,
known as a class, and controlling access to the data through the class interface.
Information hiding, on the other hand, refers to the practice of hiding the implementation
details of a class from external entities, and exposing only the necessary interface for
interacting with the class.

The purpose of encapsulation and information hiding is to create a well-structured and


maintainable codebase by promoting modularity, reducing coupling between modules,
and protecting the integrity of data by preventing unauthorized access and modification.

Advantages of Encapsulation and Information Hiding in the chosen


ADT

In the chosen ADT for the scenario, encapsulation and information hiding provide the
following advantages:

1. Data Protection: Encapsulation and information hiding ensure that the data stored
in the ADT is protected from unauthorized access and modification, as access to the data
is controlled through the class interface. This helps to prevent errors and maintain data
integrity.

34

M.G.Dineru Sahan Hiruwinda E163365 DSA


2. Modularity: Encapsulation promotes modularity by bundling data and methods
into a single unit, which can be reused and tested independently of other modules. This
makes the codebase more flexible and easier to maintain.

3. Reduced Coupling: Information hiding reduces coupling between modules by


hiding the implementation details of the ADT from external entities. This makes it easier
to modify and maintain the ADT without affecting other parts of the codebase.

4. Abstraction: Encapsulation and information hiding promote abstraction by hiding


unnecessary details of the ADT from external entities. This simplifies the interaction with
the ADT and makes the codebase more manageable.

Object Orientation and Imperative ADTs

• Object orientation is a programming paradigm that focuses on creating objects


that have state, behavior, and identity, and that interact with one another to perform tasks.

• Imperative ADTs are a type of data structure that is defined by the operations that
can be performed on it. These operations are often expressed in an imperative
programming style.

Agreement or disagreement with the statement that "Imperative ADTs are basis for object
orientation": I would disagree with the statement that "Imperative ADTs are basis for
object orientation" because while imperative ADTs can be used as building blocks for
object-oriented programming, they are not the only basis for object orientation. Object
orientation involves much more than just data structures, it encompasses the entire design
and architecture of a program, including things like inheritance, polymorphism, and
encapsulation.

C. Justification of the answer: Object orientation is a broader concept than just data
structures, as it involves designing and implementing classes and objects that interact
with each other to solve complex problems. While data structures are an important part of
object-oriented programming, they are just one piece of the puzzle. Object-oriented

35

M.G.Dineru Sahan Hiruwinda E163365 DSA


programming goes beyond just the definition of data structures and instead provides a
way to encapsulate data and behavior into objects, which can then be used to build larger
systems. Therefore, while imperative ADTs may be used in the implementation of object-
oriented programs, they are not the only basis for object orientation.

Task 04
4.1 Assess the effectiveness of data structures and algorithms.
4.1.1 Compare the performance of two sorting algorithms.

Sorting Algorithms

In order to arrange a huge collection of items in a certain order, such as alphabetically,


from highest to lowest value, or from shortest to longest distance, a sorting algorithm is
needed. Input lists are used as the starting point for sorting algorithms, and certain
operations are used to convert those input lists into sorted arrays as the final product.
Applications for sorting algorithms include the pricing-based organization of goods in an
online store or the positioning of webpages on a search engine results page.

Bubble Sort: A straightforward sorting method called bubble sort compares nearby list
items and swaps them if they are in the wrong order. Up until the complete list is sorted,
this procedure is repeated. However, because Bubble Sort has an O(n2) time complexity,
it is ineffective when dealing with big lists.

Algorithm for Bubble sort algorithm.

Step1 - algorithm Bubble_Sort(list)

Step 2 - Pre: list! = fi

Step 3 - Post: list is sorted in ascending order for all values.

Step 4 - for i <- 0 to list: Count - 1


36

M.G.Dineru Sahan Hiruwinda E163365 DSA


Step 5 - for j <- 0 to list: Count - 1

Step 6 - if list[I] < list[j]

Step 7 - Swap(list[I]; list[j])

Step 8 - end if

Step 9 - end for

Step 10 - end for

Step 11 - return list

Step 12 - end Bubble_Sort

Insertion Sort: The comparatively straightforward insertion sort algorithm loops


through a list of items and inserts each one in the appropriate location within a new list.
Although this sorting technique often has an O(n2) time complexity, it can be effective
for small lists or lists that are nearly sorted.

Algorithm for Insertion sort algorithm


Step 1 − If it is the first element, it is already sorted. return 1;

Step 2 − Pick next element.

Step 3 − Compare with all elements in the sorted sub-list.

Step 4 − Shift all the elements in the sorted sub-list that is greater than the

value to be sorted

Step 5 − Insert the value.

Step 6 − Repeat until list is sorted.

In a selection sort, the initial element is switched out for the smallest one in the list. The
next step in this process is to choose the second-smallest element and swap it with the

37

M.G.Dineru Sahan Hiruwinda E163365 DSA


first element, and so on. However, due to its time complexity of O(n2), selection sort is
not frequently employed for large lists.

A divide-and-conquer strategy known as merge sort separates the list into smaller
sublists, sorts them recursively, and then merges the sublists back together. Large lists can
be efficiently sorted using this method thanks to its O(n log n) time complexity. To store
the sublists, merge sort needs extra RAM.

Quick Sort is another divide-and-conquer algorithm that divides the list around a pivot
element that is chosen. Recursive sorting is then performed on the two resulting sublists.
Quick Sort typically has a time complexity of O(n log n), but in the worst-case scenario, it
might have an O(n2) time complexity due to improperly chosen pivots.

Heap Sort:  

Heap sorting is a sorting method that compares elements using a binary heap data
structure. The largest piece is regularly taken out of the heap and added to the end of the
sorted list. Heap sort is frequently used when the worst-case performance is better than
quicksort. It takes O(n log n) amount of time to complete.

The choice of a sorting algorithm is influenced by a number of elements, including the


amount of input, the nature of the data, and the desired performance characteristics. Each
sorting algorithm has its own benefits and drawbacks. It is essential to select the right
algorithm to sort data accurately and effectively.

Selection Sort Algorithm

The smallest (or largest) element from the unsorted part of the list is regularly chosen and
moved to the sorted part of the list using the straightforward and effective sorting
algorithm known as selection sort. The algorithm repeatedly chooses the smallest (or
largest) element from the list's unsorted section and swaps it with the unsorted section's
initial member. Up until the complete list is sorted, this procedure is repeated for the last
unsorted section of the list. A selection sort variant known as "bidirectional selection sort"

38

M.G.Dineru Sahan Hiruwinda E163365 DSA


alternates between the smallest and largest elements in the list of elements, which can
sometimes make the algorithm run more quickly.

Algorithm for Selection sort algorithm.


Step 1 − Set MIN to location 0

Step 2 − Search the minimum element in the list.

Step 3 − Swap with value at location MIN

Step 4 − Increment MIN to point to next element.

Step 5 − Repeat until list is sorted.

Quick Sort Algorithm

Quick Sort is a sorting method based on the Divide and Conquer algorithm that chooses
an element as a pivot and divides the given array around the picked pivot by placing the
pivot in the correct location in the sorted array.

Algorithm for Quick sort algorithm.

Step 1 − Make the right-most index value pivot.

Step 2 − partition the array using pivot value.

Step 3 − quicksort left partition recursively.

Step 4 − quicksort right partition recursively

Merge Sort Algorithm

Merge sort is a sorting method that breaks up a large array into smaller subarrays, sorts
each subarray separately, and then combines the sorted subarrays to form the final sorted
array.

39

M.G.Dineru Sahan Hiruwinda E163365 DSA


Algorithm for Merge sort algorithm.

Step 1 − if it is only one element in the list it is already sorted, return.

Step 2 − divide the list recursively into two halves until it can no more be divided.

Step 3 − merge the smaller lists into new list in sorted order.

4.2 Analyze the operation, using illustrations, of two network shortest path
algorithms, providing an example of each.

There are numerous shortest path algorithms that can be used to find the shortest route
between two nodes in a network. In this response, we'll discuss two of the best-known
algorithms: the Dijkstra algorithm and the Bellman-Ford algorithm.

Dijkstra's Algorithm

The greedy Dijkstra's approach is used in a weighted network to find the shortest path
between a source node and every other node. The method records all nodes, both accessed
and unaccessed. The distance to the source node is initially set to zero, while the distance
to every other node is initially set to infinite. At each step, the technique selects the
unexplored node with the least distance and explores its neighbors. Each neighbor's
distance through the current node is calculated, and if it is smaller than the previously
calculated distance, the distance is updated. The process continues until either the target
node is reached or each node has been visited once.

How to Implement the Dijkstra Algorithm?  

Before delving into the detailed use of Dijkstra's algorithm, let's take a closer look at
some of its key features. The first step in Dijkstra's method is to choose a source node,
after which it searches the complete graph for the shortest route between that node and
every other node.
The method keeps track of the current shortest path from the source node to each
individual node throughout the process, updating these values if a new, shorter path is
found.
40

M.G.Dineru Sahan Hiruwinda E163365 DSA


Once the algorithm determines the most effective path from the source node to each node,
visited nodes are marked as such and can be included in the final path.

This iterative procedure keeps going until all of the nodes in the graph are covered by the
path, making sure that a thorough path connecting every node is established while giving
the best and logically shortest paths priority.

Now explaining the step-by-step process of algorithm implementation.

All nodes are initially marked as "unvisited."


Give the chosen starting node a distance of 0, then give every subsequent node an infinite
distance.Change the current node to be the beginning node.
Add the current node's distance to the edge's weight to determine the distances between
the current node's undiscovered surrounding nodes.
Comparing the newly determined distance to the node's neighbor's current distance will
help. Update the node's current distance if the new distance is less.

Working Example of Dijkstra's Algorithm.

The section above describes the step-by-step process of the Dijkstra algorithm. Let's
investigate the algorithm using an illustrated example.

The graph's shortest path between node C and the other nodes will be found.

41

M.G.Dineru Sahan Hiruwinda E163365 DSA


 

Because node C has been selected, the least distance between each node and node C will
be recorded during algorithm execution.

In this case, the minimum distance to node C is 0. The remaining nodes will all be labeled
as infinite (), since we are unsure of their exact distances, with the exception of node C
(now shown as a red dot).

We'll now look at nodes A, B, and D, which are node C's neighbors. We will now start
with B and add the weight of the edge connecting nodes C and B (seven) to the lowest
distance of the current node (zero), resulting in the equation 0+ 7 = 7.

The smallest value still corresponds to the lowest distance to node B, which is now being
compared to this value, in this case 7, because it is less than infinite.

42

M.G.Dineru Sahan Hiruwinda E163365 DSA


 

With neighbor A, the same procedure is now confirmed. The weight of the edge joining
nodes C and A, 1, is added to 0 to get 1. 1 is the smallest value when compared to A's
infinity-minimum distance once more.

43

M.G.Dineru Sahan Hiruwinda E163365 DSA


The same is done again with node D, where 2 is noted as the lowest value.

Node C is shown as visited with a green check mark because all its neighbors have
verified that they have visited.

44

M.G.Dineru Sahan Hiruwinda E163365 DSA


The shortest minimum distance, or the node with the fewest numbers and no checkmark,
will now be used to determine the new current node's requirement to remain unvisited. In
this example, node A, the unvisited node with a minimum distance of 1, is the current
node.

Using the same procedure, we only check node B while ignoring the visited node and
looking at the node's neighbor.
The edge between nodes A and B has a weight of 3, and when we add 1 to it, we get 4 for
node B. Following comparison with the minimum distance at B, which is 7, the lowest
value at B will be noted as 4.
 

45

M.G.Dineru Sahan Hiruwinda E163365 DSA


A green checkmark indicating that Node A had been visited was then placed next to it.
Since Node D has the shortest recent distance and hasn't been visited, it is selected as the
current node. While looking for nodes B and E, we reran the algorithm.

In the case of node B, we multiply 2 by 5 to obtain 7, compare it to the node's minimum


distance value, and since 7 is more than 4, we leave the node's minimum distance value at
4.

We calculate node E's value as 2 + 7 = 9, compare it to node E's minimum distance,


which is infinite, and record the lowest value as node E's value of 9. A green checkmark
designates the node D as having been visited.

46

M.G.Dineru Sahan Hiruwinda E163365 DSA


Since node B is set as the current node, just node E has to be checked because node D has
already been visited but node E hasn't. After calculating 4+1=5, we compare it to the
shortest distance between the nodes.
Leave node E's lowest value at 5 since 9 > 5.
Node E becomes the current node when node D is marked as visited with a green
checkmark.

There is no need to check anything because it doesn't have any unchecked neighbors. A
green mark indicates that Node E has been visited.

47

M.G.Dineru Sahan Hiruwinda E163365 DSA


We have completed our work since there are no more unvisited nodes. The minimal
distance between each node and node C is now modeled by the minimal distance between
each node and all other nodes.

Bellman-Ford Algorithm

Given a graph and a source vertex, find the shortest paths between each vertex in the
graph and the source vertex. The graph could have edges that have negative weights.
We have already discussed Dijkstra's approach to this problem. The Dijkstra algorithm,
which uses the Fibonacci heap, has a time complexity of O((V+E) LogV). For graphs
with negative weights, Bellman-Ford works well, but Dijkstra does not. Bellman-Ford is
perfect for distributed systems and is less complicated than Dijkstra. However, Bellman-
Ford's temporal complexity is higher than Dijkstra's at O (V * E).

How does this work?

The algorithm, like earlier dynamic programming problems, finds the shortest paths from
the bottom up. First, we find the shortest pathways with a maximum of one edge. Then it
establishes the shortest paths that have no more than two edges, and so on. After the i-th
iteration of the outer loop, the shortest paths with at most i edges are identified. The outer
loop repeats |v| - 1 times since any simple path can only have |V| - 1 edges. The idea is as
follows, assuming there is no negative weight cycle: If we have identified shortest paths
with at most i edges, an iteration over all edges guarantees that the shortest path with at
most (i+1) edges will be generated.

The algorithm is illustrated in the following way:

Step 1: Permit setting the source vertex to zero. All distances, with the exception of the
distance to the source, should be initialized as infinite. Each edge must be processed four
times because there are five total vertices in the graph.

48

M.G.Dineru Sahan Hiruwinda E163365 DSA


Step 2: The following edges should be processed: (B, E), (D, B), (B, D), (A, B), (A, C),
(D, C), (B, C), (E, D). The following distances are determined after processing all edges
at once. The first row displays initial distances. The distances between the edges (B, E),
(D, B), (B, D), and (A, B) are shown in the second row. The third row shows distances
after processing (A, C). The fourth row indicates when (D, C), (B, C), and (E, D) are
handled.

49

M.G.Dineru Sahan Hiruwinda E163365 DSA


Step 3: The first iteration makes sure that every short pathway has a maximum of one
edge. The following distances were discovered after a second analysis of every edge (the
last row shows the results).

Step 4: The second iteration ensures that all shortest paths have a maximum of two edges.
All edges are processed twice more by the algorithm. After the second iteration, the
distances are minimized, and the third and fourth iterations do not update the distances.

Bellman Ford’s Algorithm Dijkstra’s Algorithm

Bellman Ford’s Algorithm works when there is


negative weight edge, it also detects the Dijkstra’s Algorithm doesn’t work when there is
negative weight cycle. negative weight edge.

The result contains the vertices which contains The result contains the vertices containing whole
the information about the other vertices they information about the network, not only the
are connected to. vertices they are connected to.

It can easily be implemented in a distributed It cannot be implemented easily in a distributed


way. way.

50

M.G.Dineru Sahan Hiruwinda E163365 DSA


Bellman Ford’s Algorithm Dijkstra’s Algorithm

It is more time consuming than Dijkstra’s It is less time consuming. The time complexity is
algorithm. Its time complexity is O(VE). O(E logV).

Dynamic Programming approach is taken to Greedy approach is taken to implement the


implement the algorithm. algorithm.

Task 05

5.1 Discuss how asymptotic analysis can be used to assess the effectiveness of an
algorithm.

5.1.1 What is Algorithm Analysis?

Algorithm analysis is the process of evaluating an algorithm's performance, often in terms


of its time and space complexity. One technique for evaluating an algorithm's

51

M.G.Dineru Sahan Hiruwinda E163365 DSA


performance is asymptotic analysis, which studies an algorithm's behavior as the size of
the input increases indefinitely. Experimental analysis is a method for studying
algorithms that involves running a program against a set of inputs and assessing how well
it performs in practice. Experimental analysis can give a more accurate picture of an
algorithm's performance, despite being time-consuming and occasionally useful.

5.1.2 Why is Algorithm Analysis Important?

Algorithm analysis is a critical method for anticipating algorithm behavior and


determining which algorithm is the best fit for the intended purpose since it helps to
understand how an algorithm will act in various situations. The organization can
determine an algorithm's memory requirements and execution time by looking at the
program's time and space complexity. This information can be helpful when choosing an
algorithm to solve a particular problem. By contrasting the performances of multiple
algorithms, the company can select the most effective and efficient algorithm for its
needs.Finding potential coding bottlenecks can also be accomplished through the analysis
of algorithms. If a business notices that a certain algorithm is operating slowly or
consuming a lot of memory, algorithm analysis can help it identify the root of the issue
and how to fix it. The ability to predict an algorithm's behavior under different
circumstances and comprehend its limitations are both made feasible by algorithm
analysis. You can decide when to use a particular algorithm and when to look for an
alternative strategy by using this information.

5.1.3 Experimental and Asymptotic Analysis

Assessing the performance of an algorithm can be done using two main methods: experimental
analysis and asymptotic analysis. Experimental analysis involves running the algorithm on
different inputs and evaluating its performance. This method can provide a more accurate
understanding of how the algorithm performs, but it can be time-consuming and impractical for
large input quantities. It helps identify code bottlenecks and areas where the algorithm is slow or
inefficient. However, experimental analysis has limitations as it requires writing a corresponding
program for measurement. On the other hand, asymptotic analysis allows us to compare the

52

M.G.Dineru Sahan Hiruwinda E163365 DSA


running times of algorithms without considering implementation details. It uses asymptotic
notation to express an algorithm's performance or complexity in terms of the number of steps
required for completion. Asymptotic notation helps us understand how a function behaves as
the input size increases and is a useful tool for evaluating the relative performance of different
algorithms.

5.2 Types of Asymptotic Notations in Complexity Analysis of Algorithms.

Asymptotic analysis and the worst, average, and best cases of algorithms have been
discussed. Asymptotic analysis's main objective is to offer a gauge of algorithm
efficiency that does not rely on machine-specific constants, does not require the
construction of algorithms, and does not compare the execution times of various
programs. Mathematicians employ asymptotic notations to convey the time complexity of
asymptotic analysis methods.

Theta Notation (Θ-Notation):

Theta notation is used to surround the function from above and below. Because it reflects
the upper and lower ranges of an algorithm's execution time, it is used to assess the
average-case complexity of an algorithm.
Let g and f denote the function from the set of natural numbers to itself. The function f is
referred to as being (g) if constants c1, c2, and a natural number n0 exist such that c1*
g(n) f(n) c2* g(n) for every n n0.
 

53

M.G.Dineru Sahan Hiruwinda E163365 DSA


Big-O Notation (O-notation):

The maximum permitted execution time of an algorithm is expressed using Big-O


notation. So it gives the worst-case complexity of an algorithm.

If f(n), which stands for an algorithm's running time, is a positive constant and n0 is such
that f(n) cg(n) for all n n0, then f(n) is O(g(n)).
It returns the largest possible output value (big-O) for a given input.
The execution time sets a limit on the algorithm's complexity.
 

54

M.G.Dineru Sahan Hiruwinda E163365 DSA


Omega Notation (Ω-Notation):

In omega notation, the execution time of an algorithm is displayed at its lowest bound. It
provides an algorithm's best-case complexity as a result.

The algorithm's temporal complexity is limited by the execution time.


It is defined as the situation in which an algorithm may complete an operation in the
shortest amount of time.

Let g and f denote the function from the set of natural numbers to itself. The function f is
referred to as being (g) if there is a constant c > 0 and a natural number n0 such that
c*g(n) f(n) for all n n0.

55

M.G.Dineru Sahan Hiruwinda E163365 DSA


5.2.1 How to measure the efficiency of algorithms.

Just like other areas of life, computer programming has a variety of problem-solving
techniques. Because these various ways could show different times, processing power, or
any other metric you pick, we need to evaluate the performance of several strategies
before selecting the best one.

They can carry out the same task in the present era extremely differently because of how
much they have changed. In the worst case (which happens very frequently), different
machines with different hardware and operating systems may be instructed by different
algorithms implemented in different programming languages to carry out the same task in
different ways. What an absurd notion, huh?

5.3 Time complexity represents the number of times a statement is executed.

The time complexity of an algorithm is not determined by the actual time required to run
a piece of code because that depends on other factors like the operating system,
programming language, processor speed, etc. The idea behind time complexity is that it
can only estimate how long an algorithm will take to execute based purely on the method
and its input.
To express how time-consuming a method is, we use a method called "Big O notation".
We use the Big O notation, a language, to describe how time-consuming an algorithm is.

56

M.G.Dineru Sahan Hiruwinda E163365 DSA


It helps us make decisions by allowing us to evaluate the merits of various issues'
solutions.

Big O notation describes an algorithm's run time in terms of how quickly the input (referred to as
"n") expands in comparison to the algorithm. Thus, if we were to assert, for instance, that an
algorithm's runtime increases "on the order of the size of the input," we would write it as "O(n)".
If we want to state that an algorithm's execution time increases "on the order of the square of
the size of the input," we would use the notation "O(n2)". But exactly what does that mean?

Knowing the speeds at which things might increase is essential to comprehending time
complexity. Time taken per input size is the unit of measurement here. There are various time
complexity kinds, so let's look at the most fundamental ones first.

Constant Time Complexity: O (1)

 An algorithm or operation is said to have "constant complexity" if it always takes the
same amount of time or space to complete, regardless of the size of the input. In other
words, the time or space needs of the algorithm or operation are independent of the size
of the input.

For instance, no matter how much input was provided, an algorithm with a constant time
complexity of O(1) would always require five steps to complete. Such a data structure
always uses 10 bytes of memory, regardless of the number of components it includes, and
has a constant space complexity of O(1).

 Constant complexity is often seen as being particularly desirable in algorithm design as it


ensures that the algorithm's performance is predictable and unaffected by changes in input
size. Accessing an entry in an array or adding an element to the end of a linked list are
examples of common operations with constant time complexity.

Space Complexity

Space complexity refers to the amount of memory or storage required by an algorithm to


solve a problem in relation to the size of the input. It can be measured in terms of memory
cells or bits used for data storage. There are two categories of space complexity: auxiliary
57

M.G.Dineru Sahan Hiruwinda E163365 DSA


space complexity and total space complexity. Auxiliary space complexity refers to the
additional memory needed by an algorithm outside of the input space to perform its
operations. On the other hand, total space complexity includes both the input space and
auxiliary space used by the algorithm, encompassing all data structures, variables, and
additional memory. Space complexity is often represented using Big O notation, denoted
as "S". For example, if an algorithm has O(n) space complexity, it means the space usage
grows linearly with the input size. Conversely, O(1) space complexity indicates a fixed
amount of space that remains independent of the input size. Consideration of space
complexity is crucial in algorithm design, especially for memory-constrained systems like
embedded systems or mobile devices, where high space complexity may not be feasible
or practical.

5.3.1 Interpret a trade-off specifying an ADT.

In software engineering, a trade-off occurs when improving one element of a system or


design requires compromising another. A trade-off may be made while determining how
to implement an abstract data type (ADT).

Consider the list ADT, which may be used either as an array or a linked list. If we choose
to implement the list as an array, we can gain constant-time access to every entry. It can,
however, take O(n) time to move every element after a middle-of-the-list element in order
to insert or remove it.

This is an example of how spatial and temporal complexity can be traded off. While the
array solution provides faster access times but requires more capacity to retain the entire
list, the linked list technique uses less storage space but compromises access speeds for
elements in the middle of the list.
When developing an ADT, it's crucial to assess the benefits and drawbacks of several
implementation options and select the one that best meets the demands of the application.
For instance, if quick access times are crucial, the array solution would be chosen,
whereas the linked list technique might be more appropriate if memory usage is an issue.
58

M.G.Dineru Sahan Hiruwinda E163365 DSA


5.4 Benefits of using implementation independent data structures.

Implementation independent data structures have the following advantages:


Portability: These data structures can be used across various programming languages and
platforms without requiring modifications. This promotes code reuse and facilitates
knowledge transfer between projects.

Flexibility: Programmers have more flexibility when creating and implementing


algorithms since implementation independent data structures are not tied to a specific
programming language or platform. Developers can choose the most suitable data format
for the task at hand, regardless of the language or platform being used.

Scalability: Implementation independent data structures are designed to efficiently


handle large amounts of data without sacrificing performance. This makes them suitable
for applications that involve managing substantial datasets.

Modularity: Implementation independent data structures serve as building blocks for


more complex algorithms and data structures. This allows programmers to reuse code and
construct intricate systems from smaller, modular components.

Standardization: Implementation independent data structures are often based on well-


known and widely used algorithms. They are well-documented and standardized, making
it easier for developers to understand and utilize them. This also promotes collaboration
among developers working on projects involving these data structures.

References:
 Harvard References:
 Goodrich, M.T., Tamassia, R. and Goldwasser, M.H. (2014). Data Structures and
Algorithms in Java. Wiley.
 Cormen, T.H., Leiserson, C.E., Rivest, R.L. and Stein, C. (2009). Introduction to
Algorithms, 3rd ed. The MIT Press.
 Karumanchi, N. (2011). Data Structures and Algorithms Made Easy: Data
Structures and Algorithmic Puzzles. CareerMonk Publications.
59

M.G.Dineru Sahan Hiruwinda E163365 DSA


 Lewis, J. and Chase, J. (2018). Java Software Structures: Designing and Using
Data Structures. Pearson. • Schildt, H. (2018). Java: The Complete Reference,
11th ed. McGraw Hill.
 Sierra, K. and Bates, B. (2005). Head First Java, 2nd ed. O'Reilly Media. • Bloch,
J. (2017). Effective Java, 3rd ed. Addison-Wesley.
 Goetz, B., Peierls, T., Bloch, J., Bowbeer, J., Holmes, D. and Lea, D. (2006). Java
Concurrency in Practice. Addison-Wesley.
 Sedgewick, R. and Wayne, K. (2011). Algorithms, 4th ed. Addison-Wesley.
 Lodi, A., Manzoni, M. and Monaci, M. (2017). The Shortest Path Problem: A
Review. INFORMS Journal on Computing, 29(2), pp.238-258.
 Gross, J.L. and Yellen, J. (2013). Graph Theory and Its Applications, 2nd ed.
Chapman and Hall/CRC. • Wilson, R.J. (2010). Introduction to Graph Theory, 5th
ed. Pearson.

60

M.G.Dineru Sahan Hiruwinda E163365 DSA

You might also like