0% found this document useful (0 votes)
56 views

NguyenMinhDuc Assignment1 DataStructureAndAlgorithm

The document discusses the use of abstract data types (ADTs) and algorithms in software design and development. It describes how ADTs and algorithms can be used to improve a coastal container shipping optimization project. Specifically, it aims to optimize routes to reduce costs while ensuring safety. The document provides background on data structures, algorithms, ADTs, and formal notations to specify and evaluate their performance. It emphasizes how understanding data structures and algorithms ensures efficient code and is crucial for algorithm and program design.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views

NguyenMinhDuc Assignment1 DataStructureAndAlgorithm

The document discusses the use of abstract data types (ADTs) and algorithms in software design and development. It describes how ADTs and algorithms can be used to improve a coastal container shipping optimization project. Specifically, it aims to optimize routes to reduce costs while ensuring safety. The document provides background on data structures, algorithms, ADTs, and formal notations to specify and evaluate their performance. It emphasizes how understanding data structures and algorithms ensures efficient code and is crucial for algorithm and program design.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 94

PROGRAM TITLE: BTEC (RQF) Higher National Diploma in Computing

UNIT TITLE: Data Structure and Algorithm

ASSIGNMENT NUMBER: 1

ASSIGNMENT NAME: Optimum Cargo Ship Routing(OASR)

SUBMISSION DATE: 29/10/2022

DATE RECEIVED: 30/9/2022

TUTORIAL LECTURER: Nguyen Ngoc Tan

WORD COUNT: 13383

STUDENT NAME: Nguyen Minh Duc

STUDENT ID: BKC12348

MOBILE NUMBER: 0904078692


Summative Feedback:

Strength:

Weakness:

How to improve:

Internal verification:
Table of Contents
I, Introduction 5

II, Theoretical basic 5

A, Data Structure and Algorithm 5

1, Definition of Data structures and Algorithms 5

1.1, How are data structure used? 5

1.2, Some examples of how data structures are used include the following: 5

1.3, Benefits of using data structure: 5

1.4, Disadvantages of Data structures: 6

1.5, Types of Data Structure: 6

2, What is an Algorithm? 11

2.1, Examples: 12

2.2, The importance of Algorithm? 12

2.3, Type of algorithms: 13

3, Abstract data type: 14

3.1, The advantages of encapsulation and information hiding when using an ADT:
16

4, Queue Data Structure 17

4.1, Queue Operations 18

5, What is stack. 24

5.1, Operations of stack 24

5.2, How it is used to implement function calls in a computer. 27

6, FIFO: 28

6.1, Example about FIFO: 29

7, What is graphs: 31

7.1, Dijkstra's algorithm: 32


7.2, Kruskal’s Algorithm 36

8, The view that imperative ADTs are a basic for object orientation offering a
justification for the view: 39

9, Introduction to Independent data structure 40

9.1, The three benefits of using implementation independent data structure: 41

B, Design Specification: 41

1, Specification and Description Language: 41

1.1, Organization of SDL: 43

1.2, Behavior: 45

2, Definition of software stack: 49

C, Error handling: 51

1, Error handling Testing: 51

1.1, Error handling techniques: 51

1.2, Objective of Error handling testing: 54

1.3, Advantages and Disavantages: 54

D, The effectiveness of data structures and algorithms 55

1, Algorithm analysis: 55

1.1, Importance of Performance Analysis: 55

1.2, Why is it important to analyze the performance of an algorithm: 55

2, Asymptotic Analysis: 56

2.1, Asymptotic Notations: 57

2.2, Example: 59

3, Compare the performance of two sorting algorithms. 60

3.1, Selection sort: 60

3.2, Bubble Sort: 61


4, The efficiency of an algorithm can be measured: 62

4.2, Measurement of algorithm efficiency: 63

4.3, Example: 68

5, Time-Space Trade-offs: 68

Example: 69

5.1, Types of Trade-offs: 69

5.2, Example: 70

IV, IMPLEMENTATION: 72

1, Implement an ADT and algorithm 72

2, Unit test / test documentation 72

3, Source code and evidence 74

3.1, Vertices.java class: 74

3.2, Edges.java class: 76

3.3, ShortestPathFind.class: 77

3.4, Main.java class: 78

3.5, The result: 82


I, Introduction

You work as an in-house software developer for BKC Software Company, a software
company that provides networking solutions. Your company is part of a service delivery
cooperation project and your company has won a contract to design and develop the solution
"Optimum Cargo Ship Routing". (OASR)".

Your account manager has given you a special role to inform your team about the
design and implementation of abstract data types. You have been asked to create a report for
all collaborating partners on how to use ADT to improve software design, development, and
testing, and how to specify abstract data types and algorithms in a formal notation, a way of
evaluating the performance of data structures and algorithms.

Because the coastal shipping industry is facing fierce economic competition today;
Coastal container shipping companies cannot increase profits by dramatically increasing
container mile rates as they used to. In that context, with the premise that container transport
of coastal ports can reach their destination safely, the company needs to improve the current
optimal route algorithm for coastal ports, expanding the meaning of the route. optimization
such as shortest distance, lowest cost as well as overall road evaluation lead and cost, and
perform improved algorithmic verification. By solving the problem of choosing the optimal
route for coastal shipping, the improvement will promote the rapid response of container
shipping, reduce operating costs, and improve the competitiveness of port container shipping.
coastal and economic efficiency of the algorithm, while providing new thinking for the
application of the algorithm.

II, Theoretical basic

A, Data Structure and Algorithm

1, Definition of Data structures and Algorithms

A data structure is a method of organizing data in a virtual system. Think of


sequences of numbers or tables of data - both are well-defined data structures. An algorithm
is a series of steps performed by a computer that takes input data and converts it into target
output.

Together, data structures and algorithms come together and allow programmers to
create the computer programs they need. An in-depth study of data structures and algorithms
ensures efficient and well-optimized code.

1.1, How are data structure used?

In general, data structures are used to implement the physical forms of abstract data
types. Data structures are a crucial part of designing efficient software. They also play a
critical role in algorithm design and how those algorithms are used within computer
programs. For example: JavaScript arrays and objects are common coding structures used for
storing and retrieving information.

1.2, Some examples of how data structures are used include the following:

● Storing data: Data structures are used for efficient data persistence, such as specifying
the collection of attributes and corresponding structures used to store records in a
database management system. Managing resources and services: Core operating
system (OS) resources and services are enabled through the use of data structures
such as linked lists for memory allocation, file directory management and file
structure trees, as well as process scheduling queues.
● Data exchange: Data structures define the organization of information shared between
applications, such as TCP/IP packets.
● Ordering and sorting: Data structures such as binary search trees -- also known as an
ordered or sorted binary tree -- provide efficient methods of sorting objects, such as
character strings used as tags. With data structures such as priority queues,
programmers can manage items organized according to a specific priority.
● Indexing: Even more sophisticated data structures such as B-trees are used to index
objects, such as those stored in a database.
● Searching: Indexes created using binary search trees, B-trees or hash tables speed the
ability to find a specific sought-after item.

1.3, Benefits of using data structure:

● The data structure helps to store data efficiently on the storage device.
● Using a data structure provides convenience when retrieving data from a storage
device.
● The data structure enables efficient and efficient processing of small and large
amounts of data.
● Using the correct data structure can help the programmer save a lot of time or
processing time on operations such as storing, retrieving, or processing data.
● Managing large amounts of data can be easily accomplished using a good data
structure approach.
● Most well organized data structures like array, stack, queues, chart, tree, linked list
have a well-structured and pre-planned approach to operations like store, add,
retrieve, manipulate, delete, etc. When using them, the programmer can completely
depend on these data structures.
● Using a data structure can simply promote long-term reuse.
● Data structures like array, linked list, tree, chart, stack, etc. They are well tested and
proven so anyone can use them directly without the need for research and
development.

1.4, Disadvantages of Data structures:

● In order to change data structures, we have to be very advanced IT technicians with a


large experience base. It is almost impossible to change most of the data structures.
● When we have a problem with data structures it is very unlikely that we can solve it
without the expertise of a professional.

1.5, Types of Data Structure:

Primitive Data Structures: These are the structures which are supported at the
machine level, they can be used to make non-primitive data structures. These are integral and
are pure in form. They have predefined behavior and specifications. Examples: Integer, float,
character, pointers. The pointers, however don’t hold a data value, instead, they hold memory
addresses of the data values. These are also called the reference data types.

Non-primitive Data Structures: The non-primitive data structures cannot be


performed without the primitive data structures. Although, they too are provided by the
system itself yet they are derived data structures and cannot be formed without using the
primitive data structures. The Non-primitive data structures are further divided into the
following categories:
Linear data structure: In linear data structures, elements are arranged sequentially one after
another. Since the elements are arranged in a specific order, they are easy to implement.
However, as the complexity of the program increases, linear data structures may not be the
best choice due to operational complexity.

Array Data Structure: In an array, memory elements are organized into contiguous memory.
All array elements are of the same type. And the type of elements that can be stored as arrays
is determined by the programming language.

Array operations:

● Traverse: To access each element stored in array one by one and print them.
● Search: To search the element by its value or its index
● Update: Update the value of an existing element at a given index

Linked list: A linked list is a sequential structure that consists of a sequence of items in linear
order which are linked to each other. Because, there have to access data sequentially and
random access is not possible. Linked lists provide a simple and flexible representation of
dynamic sets. The data elements are connected through a series of nodes in linked list data
structure. And, each node contains the data items and address to the next node.

Some common relation to linked list:

● Elements in a linked list are known as nodes.


● Each node contains a key and a pointer to its successor node, known as next.
● The attribute named head points to the first element of the linked list.
● The last element of the linked list is known as the tail.
A node can be added in linked list in three ways:

● At the front of the linked list


● After a given node.
● At the end of the linked list.

Linked list is divided into three categories:

Singly Linked List.

The first node is the head node and it points to next node in the sequence. The last
node’s reference is null indicating the end of the list.

Doubly Linked List.

Every node has two pointers, one for pointing to next node and the other for pointing
to the previous node. The next pointer of the last node and the previous pointer of the first
node (head) are null.

Circular Linked List.


Circular Linked List is very similar to a singly linked list except that, here the last
node points to the first node making it

Operation of linked list

● Traversal: To traverse all the nodes one after another.


● Insertion: To add a node at the given position.
● Deletion: To delete a node.
● Updating: To update a node.

Stack data structure

In the data structure of the stack, items are stored according to the LIFO principle.
That is, the last item stored on the stack will be removed first. It works like a stack of dishes,
where the last dish stored in the stack will be removed first.

Basic operations of Stack:

Several basic operations allow us to perform various actions on the stack:

● Push - Adds an item to the beginning of the stack.


● Pop - removes an item from the top of the stack.
● Is Empty: check if the stack is empty
● Is Full: check if the stack is full
● Peek: get the value of the top element without removing it

Queue data structure:


The queues follow “FIFO” mechanism for storing and retrieving elements. The
elements which are stored first into the queue will only be the first elements to be removed
out from the queue. The “ENQUEUE” operation is used to insert an element into the queue
whereas the “DEQUEUE” operation is used to remove an element from the queue.

Non-Linear Data Structure:

Unlike linear data structures, the elements of nonlinear data structures are not in any
order. Instead, they are arranged hierarchically, where an item will be associated with one or
more items. Nonlinear data structures are further classified as graph and tree-based data
structures.

Tree:

A tree is a hierarchical data structure clearly showed as a collection of nodes. Nodes


describe value and nodes are connected by edges. Linear data structures store data
sequentially but non-linear data structure not store data sequentially. But tree data structures
allow quicker and easier access to the data because it is a non-linear data structure.
A tree data structure has the following properties:

● The tree has one node called “root”. The tree begins from this, and hence it does not
have any parent.
● Not only each node has one parent but also it can have multiple children.
● Each node is connected to its children via edge.

Graph Data Structure

In a graph data structure, each node is called a vertex, and each vertex is connected to
other vertices through edges.

2, What is an Algorithm?

The algorithm is a set or arrangement of instructions implemented by a human or a


computer to do a process. These instructions help in solving a complex problem or help to
perform thecomputation of data. Computers should follow these instructions to do a
calculation or to perform problem-solving operations. They are needed for simple processes
such as the multiplication of two numbers or complex problems searching for a compressed
file’s contents. Programmers tend to develop good algorithms so that the problems are solved
in a better manner. And every computerized device uses algorithms to perform its functions.

● An algorithm is a set of instructions for solving a problem or accomplishing a task.


● Every computerized device uses algorithms, which cut the time required to do things
manually.
● Algorithmic trading, also known as automated trading or black-box trading, uses a
computer program to buy or sell securities at a pace not possible for humans.

2.1, Examples:

● Sorting Algorithm: Selecting Sort, Bubble Sort, Insertion Sort, etc.


● Searching Algorithm: Linear Search, Binary Search, etc.

2.2, The importance of Algorithm?

To improve the efficiency of a computer program:

In programming, there are different ways of solving a problem. However, the


efficiency of the methods available varies. Some methods are well suited to give more
accurate answers than others. Algorithms are used to find the best possible way of solving a
problem. In doing so they improve the efficiency of a program.

When it comes to programming, efficiency can be used to mean different things. One
of them is the accuracy of the software. With the best algorithm, a computer program will be
able to produce very accurate results.
Another way of looking at the efficiency of the software is speed. An algorithm can
be used to improve the speed at which a program executes a problem. A single algorithm has
the potential of reducing the time that a program takes to solve a problem.

Proper utilization of resources:

A typical computer has different resources. One of them is computer memory. During
the execution phase, a computer program will require some amount of memory. Some
programs use more memory space than others. The usage of computer memory depends on
the algorithm that has been used.

The right choice of algorithm will ensure that a program consumes the least amount
of memory. Apart from memory, the algorithm can determine the amount of processing
power that is needed by a program.

2.3, Type of algorithms:

Brute Force Algorithm:

A brute force algorithm essentially attempts all the chances until an acceptable result
is found. This is the most fundamental and least complex type of algorithm. Such types of
algorithms are moreover used to locate the ideal or best solution as it checks all the potential
solutions.

Recursive Algorithm:

This type of algorithm depends on recursion. In recursion, an issue is comprehended


by breaking it into subproblems of a similar kind and calling itself over and over until the
issue is unravelled with the assistance of a base condition.

Dynamic Programming Algorithm:

This type of algorithm is also called the memoization technique. This is because, in
this, the thought is to store the recently determined outcome to try not to figure it over and
over.

Divide and Conquer Algorithm:


In the Divide and Conquer algorithm, the thought is to tackle the issue in two areas,
the first section partitions the issue into subproblems of a similar sort. The second section is
to tackle the more modest issue autonomously and afterwards add the joined outcome to
create the last response to the issue.

Greedy Algorithm:

Now coming towards another type that is a greedy algorithm, so in this, the solution
is created portion by portion. The finding to select the following role is accomplished on the
purpose that it provides the sudden help and it never deems the options that had assumed
lately.

Backtracking Algorithm

In this type of algorithm, the issue is worked out steadily, for example, it is an
algorithmic-procedure for taking care of issues recursively by attempting to construct an
answer steadily, each piece, in turn, eliminating those solutions that neglect to fulfil the
conditions of the situation at any point of time.

Randomized Algorithm

In this type of algorithm, a random number is taken for deciding at least once during
the computations.

3, Abstract data type:

● Abstract Data type (ADT) is a type (or class) for objects whose behavior is defined by
a set of value and a set of operations.
● The definition of ADT only mentions what operations are to be performed but not
how these operations will be implemented. It does not specify how data will be
organized in memory and what algorithms will be used for implementing the
operations. It is called “abstract” because it gives an implementation-independent
view. The process of providing only the essentials and hiding the details is known as
abstraction.
● The user of data type does not need to know how that data type is implemented, for
example, we have been using Primitive values like int, float, char data types only with
the knowledge that these data type can operate and be performed on without any idea
of how they are implemented. So, a user only needs to know what a data type can do,
but not how it will be implemented. Think of ADT as a black box which hides the
inner structure and design of the data type. Now we’ll define three ADTs namely List
ADT, Stack ADT, Queue ADT.

Data encapsulation sometimes referred to as data hiding, is the mechanism where by


theimplementation details of a class are kept hidden from the user. This mechanism restricts a
range of operations that the user can perform on the hidden members of the class by
executing special functions commonly called methods. This idea of hiding the details away
fromthe user and providing a restricted, clearly defined interface is the underlying theme
behind the concept of an abstract data type

Benefits of Using Encapsulation

● As the data is hidden encapsulation allows objects to work independently of one


another.
● We can access information hidden in object only through its methods so it forms
interface sort of information which is consistent to the world outside of the object.
● Objects have interface through which they communicate and thus data is protected
from outside world.
● As interface if assumed is same, entire objects can be replaced with new objects.
● If encapsulation was not there, minor changes in object's behavior and state may
cause damages to the system.
● To fix bugs also encapsulation helps a lot as entire system is untouched only the
infected object will be repaired.
● In case of rewriting(adding) or changing a part of a program encapsulation is very
helpful as entire program is not required to edit means code optimization is possible
only by encapsulation.
● Encapsulation helps in protecting the internal details of objects while changing the
outer side it.
● Encapsulation of object is like chain of information box, if one box is broken it can be
repaired or replaced without disturbing the inside material of the other boxes.

3.1, The advantages of encapsulation and information hiding when using an ADT:

Data encapsulation sometimes referred to as data hiding, is the mechanism where by the
implementation details of a class are kept hidden from the user. This mechanism restricts a
range of operations that the user can perform on the hidden members of the class by
executing special functions commonly called methods. 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.

Data encapsulation’s advantages only affect the class’s implementation but the
interface is still the same. For example, a developer can choose to create a stack that contains
float numbers with lots of options such as an array (which will be chosen), linked list, and
then write push() and pop() in order to put numbers into and remove them from the array
respectively. However, in some cases, if the requirements force the developer to change the
stack's implementation to a linked list, the array just need to be replaced with the linked list
while all the implementation such as push() and pop(), which will be the same. Moreover,
this mechanism is supported in C++ and C# by using the public, protected and private
keywords during the class’s declaration.

In other word, this mechanism is also called access control. A class will grant or deny
access to its objects using the public and private access specifiers. Public objects can be
accessed by any function in a program, while the private objects are the opposite. Objects can
contain both public and private variables but only public information can be accessed.

4, Queue Data Structure

Queue is a linear data structure or abstract data type. It is also like stack data
structure. The first element that is inserted from one end is known as Rear or Tail. The other
end that the removable of existing element takes place is known as Front or Head. This data
structure is behaved according to the FIFO (First in First Out) principle. It means, when the
element is inserted first, it will be removed first.

The queue data structure is also an ordered list of elements with same data types. New
element is inserted in to the rear of the queue when inserting new element in to a queue. To
remove an element from the queue, all the elements before the removing element should be
removed in the queue.

Applications of Queue:

Queue is used when things don’t have to be processed immediately, but have to be
processed in First In First Out order like Breadth First Search. This property of Queue makes
it also useful in following kind of scenarios.

● When a resource is shared among multiple consumers. Examples include CPU


scheduling, Disk Scheduling.
● When data is transferred asynchronously (data not necessarily received at same rate
as sent) between two processes. Examples include IO Buffers, pipes, file IO, etc.

4.1, Queue Operations

When considering the queues, there are basic queue operations can be identified.

1. Enqueue – Insert an item to the queue

A queue is the maintenance of two data indicators, the front and back steps must be taken to
reserve a queue. Example:

Step 01: Check is reservation queue.

Step 02: If queue is full then produce overflow error.

Step 03: If queue is not full, increment the rear pointer to point next empty space

Step 04: Add the reservation to the queue location where rear is pointing

Step 05: Return the success reservation


After confirmation, the specific reservation should be removed from the waiting list. Add a
confirmed reservation

After the responding:

2. The client made a temporary reservation but did not respond within a day

No change will occur if the customer does not respond that the reservation should wait
3. After confirmation, the customer does not change the requirements such as location,
number of guests.

Then there is no change in the confirm reservation.

It will then be removed from the confirmed reservation and added to the waiting list
4. if the customer accepts the reservation without any changes

The customer then confirms the reservation and takes steps to remove it from the waiting list.

In addition, food is removed from the list of available foods.


5. if the customer accepts the reservation without any changes

Then go to the customer reservation confirmation reservation and remove from the waiting
list. In addition, food is removed from the list of available foods.
2. Dequeue – Remove an item from the queue

Step 01-chek if reservation queue is empty.

Step 02-if reservation queue is empty produce underflow error.

Step 03-if reservation queue is not empty, access the reservation

where front is pointing.

Step 04- increment front point to point next available reservation


Step 05 -return success delete or removed function.

For the example:

● if customer not responding with in a day.


● if customer need to be changed their requirements.
● or reject the reservation

Whether the reservation queues are empty before the function is checked means that there is
a reservation or not. If there is no blank message and an error message is given, remove the
reservation and add it to the waiting list.

After the checking reservation is not responding with in day. Then it should be removed and
give a chance to following reservation 2.
5, What is stack.

The stack can only be used for local variables that use up small amounts of memory. The
good news is that memory allocation and management will not be your problem and access
to these objects is very fast. It is subject to size limits and the fact that you cannot resize
variables on the stack.

Also A stack is a linear data structure that can be accessed only at one of its ends for
storing and retrieving data. Such a stack resembles a stack of trays in a cafeteria: New trays
are put on the top of the stack and taken off the top. The last tray put on the stack is the first
tray removed from the stack. For this reason, a stack is called a LIFO structure: last in/first
out.

5.1, Operations of stack

A tray can be taken only if there are trays on the stack, and a tray can be added to the
stack only if there is enough room; that is, if the stack is not too high. Therefore, a stack is
defined in terms of operations

that change its status and operations that check this status. The operations are as follows:

clear() — Clear the stack.


isEmpty() — Check to see if the stack is empty.

push(el) — Put the element el on the top of the stack.

pop() — Take the topmost element from the stack.

topEl() — Return the topmost element in the stack without removing it.

After pushing number 10 onto an empty stack, the stack contains only this number.
After pushing 5 on the stack, the number is placed on top of 10 so that, when the popping
operation is executed, 5 is removed from the stack, because it arrived after 10, and 10 is left
on the stack. After pushing 15 and then 7, the topmost element is 7, and this number is
removed when executing the popping operation, after which the stack contains 10 at the
bottom and 15 above it.

Generally, the stack is very useful in situations when data have to be stored and then
retrieved in reverse order. One application of the stack is in matching delimiters in a
program. This is an important example because delimiter matching is part of any compiler:
No program is considered correct if the delimiters are mismatched.

Generally, the stack is very useful in situations when data have to be stored and then
retrieved in reverse order. One application of the stack is in matching delimiters in a
program. This is an important example because delimiter matching is part of any compiler:
No program is considered correct if the delimiters are mismatched.

Stack exception.

● Operations pop and top can’t be performed if the stack is empty.


● Attempting the execution of pop or top an empty stack should throws a
StackEmptyException.
● Operations push sometimes can’t be performed if it’s not enough memory.
● Attempting the execution of push when there is not enough memory should throws a
Out of Memories errors.

Application of stacks.

● Any sort of nesting (such as parentheses)


● Evaluating arithmetic expressions (and other sorts of expression)
● Implementing function or method calls.
● Keeping track of previous choices (as in backtracking)
● Keeping track of choices yet to be made (as in creating a maze)
● Undo sequence in a text editor
● Auxiliary data structure for algorithms
● Component of other data structure

Functionalities

o Common characteristics
● Object[] a
● Int top, max
o Constructors
● ArrayStack(int max)
● ArrayStack() – default max = 50
o Common behaviors
● isEmpty() – Return true if the stack includes no element and false otherwise.
● isFull() – Return true if the stack is full
o clear() – Clear all element of stack
● grow()
o push() – push an element into the stack
● top()
o pop() – Remove the top element of the stack and return it; throw
EmptyStackException for empty stack

When the method finishes executing, its corresponding stack frame is flush, the flow returns
to the calling method and the available space for the next method.
For example: Declaring int i = 4 it will put i = 4 on the stack Declaring y = 2 it will put y = 2
on the stack (stacked on i = 4) Declaring class1 cls1 = new class1 (): this is an object type, so
it will create cls1 object

in the heap and not refer to the object of cls1 on the stack (top in the stack). Stacks are a
special type of list where the addition or removal of an element is done at one end of the list
called a top. In other

words, the stack is a data structure with two basic operations: addition (push) and removal
(pop), in which the removal will progress.

Push: Add an element to the top of the stack, meaning after the elements are already in the
stack.

Pop: Releases and returns the element standing at the top of the stack.

The advantages of Stack-based CPU organization:

● Effective calculation of complex arithmetic expressions.


● Executing instructions is fast because the operand data is stored in consecutive
memory locations.
● The length of the instructions is short because they do not have an address field.
● The disadvantages of organizing CPU based on Stack:
● The scale of the program increased.

5.2, How it is used to implement function calls in a computer.

Before executing a function, a program pushes all the parameters for the function to the
stack in the reverse order in which they were recorded. The program then issues a call telling
which function it wants to start. Instruct the call to do two things:

● First, it pushes the address of the next instruction, the return address, onto the stack.
● Then, it modifies the command cursor to point to the beginning of the function.

A call stack consists of stack frames (also called activation records or activation frames).
These are machine-dependent data structures and the ABI contains subroutine status
information.
Each stack frame corresponds to a call to the subroutine that has not ended with a return. For
example, if a subroutine called Draw Line is currently running has been called by a Draws
ape subroutine, the top of the call stack may be laid out as shown in the next picture.

A diagram like this can be drawn in either direction as long as the position of the
vertex. So the direction of stack development is understood. Moreover, independently of this,
the different architectures about whether call stacks grow to higher addresses or towards
lower addresses. The logic of the diagram is independent of the address choice.

The stack frame at the top of the stack is for the currently executing routine. The
stack frame usually includes at least the following items (in push order):

● The arguments (parameter values) passed to the routine (if any);


● The return address back to the routine's caller (e.g. in the DrawLine stack frame, an
address into DrawSquare's code); and space for the local variables of the routine (if
any).

6, FIFO:
FIFO stands for first in, first out. It is a method for processing data structures where the first
element is processed first and the newest element is processed last. It is a method for
processing data structures where the last element is processed first and the first element is
processed last.

Where is FIFO used:

● Data structure. Certain data structures such as Queues and other variants of Queues
use the FIFO method to process data.
● Disk scheduling. The disk controller can use FIFO as a disk scheduling algorithm to
determine the order in which to serve disk I/O requests.
● Communication and Networking.

Where is synchronous FIFO used?

Fifo (first in - first out) is used to transmit serial information whenever there is a difference in
the baud rate. The baud rate may vary due to the difference in port number, frequency or data
width between source and destination.

What is the principle of FIFO?

FIFO is “first in, first out” and simply means that you need to label your foods with the date
you stored them and put old foods on the front or top for you to use first. This system allows
you to find foods faster and use them more efficiently.
6.1, Example about FIFO:

The following Java code example implements a simple FIFO queue with two operations,
enqueue and dequeue to insert and retrieve the element respectively:

package FIFO_ex;

public class FifoQueue<T> {

private Object[] fifoqueue;


private int size;
private int front = 0;
private int rear = 0;
private boolean checkEmpty = true;

public FifoQueue(int size) {


this.fifoqueue = new Object[size];
this.size = size;
}

public void enqueue(T elm) throws Exception {

if (front == rear && !checkEmpty) {


throw new Exception("Can't enqueue " + elm);
}

fifoqueue[rear] = elm;
rear = (rear + 1) % size;
checkEmpty = false;
}

public T dequeue() throws Exception {


if (checkEmpty) {
throw new Exception("This queue is empty");
}

T elm = (T) fifoqueue[front];


front = (front + 1) % size;
checkEmpty = (front == rear);
return elm;
}

public static void main(String[] args) throws Exception {

FifoQueue<Integer> fq = new FifoQueue<Integer>(4);

fq.enqueue(50);

System.out.println(fq.dequeue());
}

A simple test driver for queues. It creates the queue, inserts and the element, and then fetches
and prints the element. Here are the results:

7, What is graphs:
Simply put, graphs are data structures that are used to represent the links between a
pair of elements, where these elements are called nodes (or vertices), which are usually
real-time objects, people, or entities, and the links between nodes are called edges. Also, two
nodes are connected only if there is an edge between them.

“A graph is essentially a relationship of nodes/vertices connected by edges.”

Typically, graphics are suitable for real-life applications such as graphics that can be used to
illustrate a transportation system/network where nodes represent objects that transmit

or receive products and edges represent routes or subways connecting nodes.

The diagrams can be divided into two parts:

● Undirected graphs: For every pair of connected nodes, if a person can move from one
node to another in both directions, then the graph is called an undirected graph.
● Directed graphs: For every pair of connected graphs, if a person can move from one
node to another in a certain (unique) direction, then the graph is called a directed
graph. In this case, instead of simple lines, arrows are used to indicate directed edges.

Weighted graph:

Weight charts are charts where the edges of the chart have a "weight" or "cost" and also
where the weight can reflect distance, time, money, or anything else that shows an
"association" between the pair of nodes it links. These weights are an important element of
Dijkstra's algorithm.
7.1, Dijkstra's algorithm:

Dijkstra's algorithm uses breadth-first search (which is not a single source shortest path
algorithm) to solve the single source problem. Impose a restriction on the graph: there cannot
be edges with a negative weight. However, due to this single limitation, Dijkstra

significantly improves Bellman-Ford's run time.

Dijkstra's algorithm is also sometimes used to solve the shortest path problem for all pairs by
simply running it on all vertices in a VV. Again, this requires that all edge weights be
positive.

Illustration for Dijkstra's Algorithm:

The algorithm will generate the shortest path from node P1 to all the other nodes in the
graph. For this graph, the weight of the edges will assume to represent the distance between
two nodes.
They will have the shortest path from node P1 to node P2, from node P1 to node P4, and so
on for every node in the graph.

Now the point need to start and check the distance from node P1 to its adjacent nodes. As
shown, these are nodes P2 and P3. Here are with two minimum distance 5km. therefore, we
move on to visit P4.
Now the visited node P4 will check node P5 and P6. As P4 is 5, P5 will add the minimum
distance of current node (5) with the distance of the edge (11). Then it will link to the node
P6.

After this, node P1, P2, P4 and P3 marked as visited with a dark blue in color. Now the
current node is selected for minimum distance as node P4 selected, P5 and P6 are unvisited
and have a little big distance. From the visited node P3, there can move P5 and P6 that is
with a green edge in color.
The graph shows the final result except P5, with the shortest path from node P1 to each node.
In the graph, the green lines mark the edges that belong to the shortest path. They need to
follow these edges to find the shortest path to reach a given node in the graph starting from
node P1.

For example, if they want to reach node P6 starting from node P1, they just need to follow
the green edges and they will be following the shortest path P1 > P2 > P3 and >P6.

Since a complete path is obtained, they stop the algorithm here. The minimum distance for
the path thus obtained is 2+3+4+5+6=20.

P1 P2 P3 P4 P5 P6
P1 0 ∞ ∞ ∞ ∞ ∞
P2 0 3 ∞ 5 ∞ ∞
P4 0 3 5 5 ∞ ∞
P3 0 3 5 5 11 14
P6 0 3 5 5 11 9
P5 0 3 5 5 11 9

7.2, Kruskal’s Algorithm


The main idea behind the Kruskal algorithm is to sort the edges based on their weight. After
that, we start taking edges one by one based on the lower weight. In order to do this, we can
use a disjoint set data structure. The disjoint set data structure allows us to easily merge two
nodes into a single component. Also, it allows us to quickly check if two nodes were merged
before.

Some common points for algorithm as follow:

1. Initialize an array for storing the groups of the vertices.

2. Initialize an array for storing the edges of the graph with their weights.

3. Initialize the spanning tree as an empty array.

4. Put all vertices of the graph into different groups.

5. Sort the array of edges in increasing order of weights.

Illustration for Kruskal's Algorithm:


Firstly, P2 and P3 have to pick the first edge which has the minimum distance. P2 and P3 are
picked here, which distance 2km.

Then, P1 and P2 pick the edge with the second minimum distance. P1 and P2 are picked here
since it distance 3km.
P3 and P6 pick the edge with the third minimum distance. P3 and P5 are picked here since it
distance 4km.

P1 and P4 pick the edge with the fourth minimum distance. P1 and P4 are picked here since
it distance 5km.
Proceeding further, P4 and P5 find that the last edge with minimum distance is P4 and P5.
The distance of this edge is 6km.

Since a complete tree is obtained, they stop the algorithm here. The minimum distance for
the tree thus obtained is 2+3+4+5+6=20.

8, The view that imperative ADTs are a basic for object orientation offering a
justification for the view:

The essence of object oriented programming is procedural data abstraction where


procedures are used to represent data and procedural interfaces provide information hiding
and abstraction. This technique complements ADTs that use concrete algebras to represent
data, and abstraction of types provides information hiding. The two paradigms can be derived
from the basic dichotomy by decoupling a set of observers and constructors that define
abstract data. CCP divides this array into constructors: each constructor has a class associated
with it, and observations become attributes or methods of instances of the class. Indeed,
values in abstraction are nothing more than a collection of legal statements about them.
ADTs, on the other hand, decompose a sequence into observations: each observation is an
operation defined in an abstract type that includes constructors as representation options.
This is because mandatory ADTs are fundamental to object orientation. This is because ADT
is one of the main components of object orientation.

Here the ADT is doing the work that we do inside the system, from the outside
perspective of the system that the meetings cannot perceive. Take, for example, our system.
In other words, all the food we take into our mouth is processed by the stomach system, but
we do not see it. This also applies to abstraction. That is, regardless of whether we enter
information by one method, its interaction occurs in another method. So, whether or not we
consider object orientation, such a loop exists. Thus, the importance of these mandatory
ADTs for object orientation can be clearly stated. In addition, one of the mandatory elements
of ADT is to limit the complexity of the code we create and maintain the quality and speed of
the system. Therefore, we treat this ability as the fundamental ability of the matter aspect.
This is due to the fact that the system we are creating can be divided into separate elements in
order to eliminate the complexity of our system and unnecessary lines of code. Then at this
moment there will be no problems with the speed and adequacy of our system. This is
because the meaningless system string size has been omitted. Thus, these components
involve the use of object orientation with ADTs, which can lead to a clear conclusion that
Mandatory ADTs are starting to direct the package for object orientation and that ADTs are
the foundation of object orientations.

9, Introduction to Independent data structure

Independent data structures are designed not to reveal any information beyond that
necessarily provided by the contents of the data structure. Independent data structure, not just
the pointer structure, must not divulge information about previous states of the data structure.
Data structure is independent if nothing can be learned from the data structure’s memory
representation during these observations except for the current abstract state of the data
structure. Any strong independent implementation of a Data Structure must satisfy a natural
canonicity criterion. For example, a strongly independent implementation of a hash table has
the property that up to randomness in the initialization of the hash table, that is the choice of
hash functions, the hash table’s representation in memory is deterministically given by its
contents.

An abstract data structure defines the set of operations for a data structure and its
semantics. A data structure’s state is the current value or contents of the data structure as
specified by its abstract data structure. A data structure’s representation in memory for any
given state is the physical contents of memory that represent that state. An implementation of
an independent data structure gives a map from any valid operation pair to a new
representation and possible output.

9.1, The three benefits of using implementation independent data structure:

● Efficient memory use: By the efficient use of data structure the uses of memory can
be optimized. If the size of data is not sure then we can use linked list vs array data
structure. If there is no more use of memory, then it can release.
● Reusability: It can be reused, once we implemented a particular data structure, we can
use it any other place. The implementation of the data structure can be compiled into
libraries which can be used by different clients.
● Abstraction: Data structures serves as the basis of abstract data types, the data
structure defines the physical forms of ADT(Abstract Data Type).

B, Design Specification:

1, Specification and Description Language:

SDL (Specification and Description Language) is one of the specification languages.


It is known to be focused on the description and unambiguous specification of the behavior
of both reactive and distributed systems.

SDL can be defined as the one focused on telecommunication systems. In 2016 its
current areas of the application included the real-time applications and the process control. It
can be also used for representing the simulation systems without ambiguity as well as with a
graphical notation.

The Specification and Description language is known to be formally complete, being


used for code generation for either final targets or simulation. It covers five main aspects:
communication, structure, behavior, inheritance, and data. The behavior of the mentioned
components is explained by partitioning the system into different hierarchies.

Communication between the components can be performed through different gates


that are connected by channels. The mentioned channels are known to be of delayed channel
type. That is the reason such communication is usually asynchronous. At the same time,
when the delay is set to zero, then such communication becomes synchronous.
The Specification and Description Language (SDL) solution was developed for
ConceptDraw DIAGRAM users to simplify their work with an implementation language as
well as building the so-called real-time systems which are involved in the parallel processing.

Having a comprehensive selection of connectors and other diagram elements, the


Specification and Description Language (SDL) solution allows all the ConceptDraw
DIAGRAM users to create the professionally-looking SDL diagrams as well as other
SDL-related drawings.

All systems engineers, as well as many other engineers, might find the Specification
and Description Language (SDL) solution truly useful in their work.

Design Elements — SDL Connectors

Design Elements — SDL Diagrams


1.1, Organization of SDL:

● System: The overall design is called the system and everything that is outside the
system is called the environment. There is no specific graphical representation for the
system but the block representation can be used if needed.
● Agent: An agent is an element in the system structure. There are two kinds of agents:
blocks and processes. A system is the outermost block.

Element Description Symbol


Block ·A block is a structuring element that does not
imply any physical implementation on the target.
·A block can be further decomposed in blocks
and so on allowing to handle large systems.
·A block symbol is a solid rectangle with its
name in it
Process A process is basically the code that will be
executed. It is a finite state machine based task
and has an implicit message queue to receive
messages. It is possible to have several instances
of the same process running independently. The
number of instances present when the system
starts and the maximum number of instances are
declared between parentheses after the name of
the process.
The full syntax in the process symbol is:
<process name>[(<number of instances at
startup>, <maximum number of instances>)]
If omitted default values are 1 for the number of
instances at startup and infinite for the maximum
number of instances.

● Architecture: The overall architecture can be seen as a tree where the leaves are the
processes.
1.2, Behavior:

First of all a process has an implicit message queue to receive the messages listed in
the channels. A process description is based on an extended finite state machine. A process
state determines which behavior the process will have when receiving a specific stimulation.
A transition is the code between two states. The process can be hanging on its message queue
or a semaphore or running e.g. executing code. A message stimulus coming from the
environment or from another agent to an agent is called a signal. Signals received by a
process agent are first placed in a queue (the input port). When the state machine is waiting
in a state, if the first signal in the input port is enabled for that state it starts a transition
leading to another state.
2, Definition of software stack:

An application is made of a set of functions that work together in a defined architecture to


provide the user with specific services. Three layers make up the most application
architecture:

● Layer of presentation: when a client accesses an application through a website or


web-based application portal, they see the presentation layer
● Logic layer: the logic layer stores application logic and business rules, wich aids in
the fulfillment of application requests. This layer performs calculations and make
decisions about how to handle request while supervising data flow between the data
layer and the presentations layer
● Data layer: is a server-side system that sends data to the logic layer when it’s time to
complete a computation or deliver it to the presentation layer, where users can view it
Each of these layers has its own set of programming languages and software tools that it
needs to set up and maintain its functionality. HTML5, JavaScript, and CSS are
examples of languages that can be used to create a web-based presentation layer.
Java, C#, Python, or C++ could be used to create the application layer. Back-end
servers could be maintained using applications like MySQL and MongoDB.

The term "Software Stack" refers to the collection of components that work together to
support application execution. Some software components are used to power back-end
processes, while others are used in the presentation layer to enable user interface. In any case,
the components of a software stack work together to deliver application services to the
end-user as quickly as possible.

Parts of a software stack:

There are four tiers in an application, three of which are server-side. This diagram
depicts how a stack works: the client is where it all begins and ends.

● In the browser, the client tier is the only component.


● The web tier is comprised of the web server (also known as an HTTP server).
● The application server (which includes the development platform, frameworks,
and server-side programming languages) is the business tier.
● The database tier—the database server you select, which is frequently influenced by
the business tier.
C, Error handling:

1, Error handling Testing:

Error handling testing is a type of software testing performed to test the system's
ability to handle errors and exceptions in the software at runtime. This testing is done with
the help of both developers and testers. Error handling techniques should include handling
both errors and exceptions.

1.1, Error handling techniques:

There are different types of error handling techniques that make it easy to deal with
errors encountered during testing. Testing technique is a great way to solve problems/errors
that testers often face when doing testing process for a particular software.

The testing techniques aim to take into account the different situations that may arise
in the case of both manual and automated testing. Therefore, the testing techniques are
devised in such a way as to ensure that all the necessary facts are covered. Below is a list of
all the testing techniques that help in assessing the possibilities of failure and taking
preventive measures.

Human-based testing:

● User testing
● Alpha Testing - Experimenting
● Beta testing - Testing
● Subject expertise test
● Pairing test

Check based on coverage:

● Functional testing
● Feature integration testing
● Check out the GUI
● Domain Check
● Equivalence class analysis
● Boundary test

Steps involved in error handling check


● Test Environment: The software testing technique influences the setup of the test
environment so that the testing process can run smoothly. This step includes planning
for testing. A system that is going to be tested is made sure have to less significant
data as there might be crashes in the system during testing.
● Test case Generation: Generate the test cases create the deliberate errors and
exceptions and observe for the software handles it. Suppose software operates on
fractions then setting the denominator of a fraction is zero. Test case generation is
associated with the developing team as without knowing the internal code, test cases
will not be designed.
● Test Case Execution: Once the test case generation and the real testing process begin,
it is the most prominent part of the testing process. It includes running the program
over the test case generated.
● Result Analysis: Execution of the test case, its result is analyzed. It involves testing
the inconsistency of the expected output for generated test cases. There may be a
chance of the program is going into an infinite loop which will lead up to software
failure.
● Re-test: If the testing has failed, it is reported as a defect to developers. After the
defect is fixed, then once more all the above steps are performed to test the system. It
also includes the system under new test cases generated.

1.2, Objective of Error handling testing:

● To check the system ability to handle errors.


● To check system highest soak point.
● To do sure errors can be handles properly by the system in the future.
● To do system capable of execution handling also.

1.3, Advantages and Disadvantages:

In Error handling, it mentions to the expectation, finding, and resolving errors of


programming, application, and communications. Some applications have presented
specialized programs, it means error handlers. It can:

● Recover the error when the error occur without ending the application
● Gracefully end an affected application and then save the error information to a log file
● Makes very easier for developers to use the code correctly, reduce the number of
errors in the code.
● Error handling makes easy to maintain the code, then, it will made easier to insert
input specifications into the code
● Help the users don’t have to look up the design when they write and later maintain the
code
● It can supply a report of accurately how the bugs happened. Therefore, it can fix the
errors. Therefore, error handling is mostly important for programming.
But, it does not handle the errors in the program, the program may crash

D, The effectiveness of data structures and algorithms

1, Algorithm analysis:

Algorithms are an important part of computational complexity theory, which provides


a theoretical estimate of the resources needed by an algorithm to solve a particular
computational problem. Analysis of an algorithm is the determination of the amount of time
and space resources required to execute it.

In the analysis of the algorithm, it usually focuses on CPU usage (time), memory usage,
disk usage and network usage. All are important, but the most concern is about CPU time. Be
careful to distinguish between:

● Performance: How much time/memory/disk/etc. used when a program is run. This


depends on the machine, compiler, etc. as well as the code we write.
● Complexity: How large are the resource requirements of a program or algorithm, i.e.
what happens when the size of the problem being solved by the code is larger.

1.1, Importance of Performance Analysis:

Importance-Performance Analysis (IPA) is an established method of measuring


service quality, well known for its simplicity and ease of use. In this way, IPA focuses on the
gap between the customer's expectations of importance and the performance judgment of a
particular attribute of the service being consumed. We distinguish three main steps in the
performance analysis process: data collection, data transformation, and data visualization.
Data collection is the process by which we obtain program performance data from the
executable program. The data is collected in a file during or after execution, although in these
situations it is presented to the user in real time.

1.2, Why is it important to analyze the performance of an algorithm:

Consider two programmers “A” and “B”. Both of them submitted 2 different
solutions to the same program. Now how do we decide which solution works and works
better? And A's program may also work better for small number of inputs but won't work as
input size increases. Similarly, B's program won't work when the input size is small but will
work better for a large number of inputs.

Therefore, to determine which solution is better, we need to analyze the performance of


the algorithm, and more specifically, consider 2 important factors that determine the
performance of an algorithm:

● Time complexity
● Spatial Complexity

Not only that, the algorithm performance analysis also helps us:

● Predict the behavior of an algorithm without implementing it on a specific computer.


● It is much more convenient to have simple measures for the efficiency of an
algorithm than to implement the algorithm and check the efficiency every time a
certain parameter in the underlying computer system changes.
● By analyzing different algorithms, we can compare them to determine the best
algorithm for our purposes.

2, Asymptotic Analysis:

Asymptotic analysis of an algorithm refers to determining the mathematical


limit/basis of its performance at runtime. Using asymptotic analysis, we can very well
determine the best case, average case, and worst case of an algorithm.

Asymptotic analysis is input-bound, that is, if there is no input to the algorithm, it is


concluded that it runs in constant time. Other than "input", all other factors are assumed to be
constant.

Asymptotic analysis refers to the calculation of the execution time of any operation in
mathematical units of calculation. For example, the execution time of an operation is
calculated as f(n), and for another operation it can be calculated as g(n2). This means that the
execution time of the first operation will increase linearly as n increases, while the execution
time of the second operation will increase exponentially as n increases. Similarly, the
execution time of both operations will be almost the same if n is significantly small.

Generally, the time required by the algorithm is divided into three types.
● Best Case – Minimum time required for program execution.
● Average Case – Average time required for program execution.
● Worst Case – Maximum time required for program execution.

The aim for using asymptotic analysis is used for characterizing the running time and the
amount of space algorithms use or characterize the functions that do nothing. It not only
helps to estimate efficiency of a function but also helps in comparing relative performance of
alternative algorithms.

2.1, Asymptotic Notations:

The commonly used asymptotic notations follows to calculate the running time
complexity of an algorithm.

Theta notation:

This notation describes both upper bound and lower bound of an algorithm so we can
say that it defines exact asymptotic behaviour. In the real case scenario the algorithm not
always run on best and worst cases, the average running time lies between best and worst and
can be represented by the theta notation.

Omega notation:
Expressing the lower bound of an algorithm's running time is the formal way of the
notation Ω (n). It measures the best case time complexity or the best amount of time an
algorithm can possibly take to complete.

Big-O notation:

Big O notation specifically describes worst case scenario. It represents the upper
bound running time complexity of an algorithm. We take few examples to understand how
we represent the time and space complexity using Big O notation.
● Big O notation O (1) represents the complexity of an algorithm that always execute in
same time or space regardless of the input data.
● Big O notation O (N) represents the complexity of an algorithm, whose performance
will grow linearly (in direct proportion) to the size of the input data.
● Big O notation O (n^2) represents the complexity of an algorithm, whose
performance is directly proportional to the square of the size of the input data.
● Similarly there are other Big O notations such as: Logarithmic growth O (log n),
log-linear growth O (n log n), exponential growth O
● (2^n) and factorial growth O (n!).

2.2, Example:
In above code “Hello World!!!” print only once on a screen. So, time complexity is
constant: O(1) every time constant amount of time require to execute code, no matter which
operating system or which machine configurations you are using.

Lets see how many times count++ will run.

● When i=0 , it will run 0 times.


● When i=1, it will run 1 times.
● When i=2, it will run 2 times and so on.

𝑁(𝑁−1)
Total number of times count++ will run is 0+1+2+…+(N-1)= 2
. So the time complexity
2
will be O(𝑁 )

3, Compare the performance of two sorting algorithms.

3.1, Selection sort:

Selection sort selects i-th smallest element and places at i-th position. This algorithm divides
the array into two parts: sorted (left) and unsorted (right) subarray. It selects the smallest
element from unsorted subarray and places in the first position of that subarray (ascending
order). It repeatedly selects the next smallest element.

Time Complexity:

● Best Case [O(N2)]. Also, O(N) swaps.


● Worst Case: Reversely sorted, and when the inner loop makes a maximum
comparison.
● [O(N2)] . Also, O(N) swaps.
● Average Case: [O(N2)]. Also, O(N) swaps.

Space Complexity: [ auxiliary, O(1)]. In-Place sort.


Advantage:

● It can also be used on list structures that make add and remove efficient, such as a
linked list. Just remove the smallest element of unsorted part and end at the end of
sorted part.
● The number of swaps reduced. O(N) swaps in all cases.
● In-Place sort.

Disadvantage: Time complexity in all cases is O(N2), no best-case scenario.

3.2, Bubble Sort:

Bubble sort repeatedly compares and swaps (if needed) adjacent elements in every pass. In

i-th pass of Bubble Sort (ascending order), last (i-1) elements are already sorted, and i-th
largest element is placed at (N-i)-th position, i-th last position.

Time Complexity:

● Best Case Sorted array as input. Or almost all elements are in proper place. [ O(N) ].
O(1) swaps.
● Worst Case: Reversely sorted / Very few elements are in proper place. [O(N2)].
O(N2) swaps.
● Average Case: [O(N2)] . O(N2) swaps.

Space Complexity: A temporary variable is used in swapping [auxiliary, O(1)]. Hence it is


In-Place sort.

Advantage:

● It is the simplest sorting approach.


● Best case complexity is of O(N) [for optimized approach] while the array is sorted.
● Using optimized approach, it can detect already sorted array in first pass with time
complexity of O(1).
● Stable sort: does not change the relative order of elements with equal keys.
● In-Place sort.
Disadvantage: Bubble sort is comparatively slower algorithm.

4, The efficiency of an algorithm can be measured:

Computer resources are limited that should be utilized efficiently. The efficiency of
an algorithm is defined as the number of computational resources used by the algorithm. An
algorithm must be analyzed to determine its resource usage. The efficiency of an algorithm
can be measured based on the usage of different resources.

For maximum efficiency of an algorithm we wish to minimize resource usage. The


important resources such as time and space complexity cannot be compared directly, so time
and space complexity could be considered for an algorithmic efficiency. The efficiency of an
algorithm can be measured by determining the amount of resources algorithm consumes.

Factors that affect the efficiency of an algorithm include speed, time and size of the input.
Primary resources that an algorithm consumes are as follows:

● Space complexity: space complexity of an algorithm or a computer program is the


amount of memory space required to solve an instance of the computational problem
as a function of characteristics of the input. It is the memory required by an algorithm
until it executes completely.
● Time complexity: the amount of time taken by an algorithm to run, as a function of
the length of the input. It measures the time taken to execute each statement of code
in an algorithm

To compute the efficiency of an algorithm, user can write a program based on algorithm
or pseudocode, execute it and measure the time. Time complexity Time complexity is the
relationship of calculation time and amount of input. This is usually about the size of an array
or an object. Time complexity is also not useful for simple functions such as fetching
usernames from databases, concatenating strings or encrypting passwords. It is used more to
sort functions, recursive calculations and things that often take longer to calculate. The
algorithm's time complexity indicates the total time that the program requires to run until it is
completed. The time complexity of the algorithms is most commonly expressed using a large
O symbol. Time complexity is most commonly estimated by counting the number of basic
steps performed by any algorithm to complete execution
4.2, Measurement of algorithm efficiency:

Sometimes people talk about the effectiveness of an algorithm, they will talk about
something called computational complexity. Basically, how difficult your algorithm is to
execute depends on the input. It's very important to note the input part, as algorithms in the
most common case work differently depending on how the input looks. To reflect that has
best, average, and worst-case computational complexity, which also means the best possible
input, the worst possible input, and the average case for the yes input fixed size.

So how to measure the computational complexity of an algorithm? By basic


definition, you analyze your algorithm for how it responds to changes in your input size.
Suppose you have input of size n. Programmers often use Big O as a means of comparing the
effectiveness of different ways of dealing with the same problem.

The Big O concept can be summarized into a short sentence as follows: How fast
time runs, depends on the input value -input, because the input value will grow when the
program runs. Just understand the Big O concept in a simple way as follows:

How fast runtime - It is difficult to determine the exact run time of an algorithm.
Because each computer with a different configuration will produce a different result
depending on the CPU, the memory of the machine. So, instead of asking the question "How
exactly is the time spent?", We should use Big O to approach the problem in the direction of
"How fast is time running?"

It depends on the input value. If measuring an exact running algorithm takes how
long you can measure in specific time units like seconds or milliseconds, but with Big O we
will use the input measurement unit - here called "N". So programmers often take the unit
based on the complexity of the algorithm with the input "n" to calculate the program's run
time.

Because the input value will grow as the program runs. When you start running the
program, people often think that it will be a waste of effort if you write a complex algorithm
to process small input values, but through each step of that algorithm, the initial value which
gradually becomes smaller So bigger things are completely different, no one cares about the
complexity of that algorithm. With Big O analysis, the programmer is only interested in other
factors that are consumed (time, storage capacity) when the input value gets bigger. That is
why the "Big O analysis" is sometimes called the "asymptotic calculation".

Common growth rates:


Order-of-Magnitude Analysis and Big O Notation:

● If Algorithm A requires time proportional to f(n), Algorithm A is said to be order


f(n), and it is denoted as O(f(n)).
● The function f(n) is called the algorithm’s growth-rate function.
● Since the capital O is used in the notation, this notation is called the Big O notation.
● If Algorithm A requires time proportional to n2, it is O(n2).
● If Algorithm A requires time proportional to n, it is O(n).

Order of an Algorithm:

Definition of the order of an algorithm:

● Algorithm A is order f(n) – denoted as O(f(n)) – if constants k and n0 exist such that
A requires no more than k*f(n) time units to solve a problem of size n ≥ n0.
● The requirement of n ≥ n0 in the definition of O(f(n)) formalizes the notion of
sufficiently large problems. In general, many values of k and n can satisfy this
definition.

In general, many values of k and n can satisfy this definition.


● If an algorithm requires n2–3*n+10 seconds to solve a problem size n. If constants k
and n0 exist such that k*n2 > n2–3*n+10 for all n ≥ n0.
● The algorithm is order n2 (In fact, k is 3 and n0 is 2) 3*n2 > n2–3*n+10 for all n ≥ 2 .
● Thus, the algorithm requires no more than k*n2 time units for n ≥ n0 , so it is O(n2)

Growth-Rate functions:
Properties of Growth-Rate Functions:

We can ignore low-order terms in an algorithm’s growth-rate function.

● If an algorithm is O(n3+4n2+3n), it is also O(n3).


● We only use the higher-order term as algorithm’s growth-rate function.

We can ignore a multiplicative constant in the higher-order term of an algorithm’s


growth-rate function.

● If an algorithm is O(5n3), it is also O(n3).


O(f(n)) + O(g(n)) = O(f(n)+g(n))

● If an algorithm is O(n3) + O(4n2), it is also O(n3 +4n2) So, it is O(n3).


● Similar rules hold for multiplication.

4.3, Example:

Cost Times
i = 1; c1 1
sum = 0; c2 1
while ( i <= n){ c3 n+1
i = i + 1; c4 n
sum += i; c5 n
}

T(n) = c1 + c2 + (n+1)*c3 + n*c4 + n*(n+1)*c5

= (c3+c4+c5)*n + (c1+c2+c3)

= a*n + b

So, the growth-rate function for this algorithm is O(n)

5, Time-Space Trade-offs:

The best algorithm, and therefore the best program for solving a given problem, is the
one that requires the least amount of memory and takes the least amount of time to execute
its instruction or generate output. But in practice, it is not always possible to achieve both
goals. As stated above, there can be more than one approach to solving the same problem.
One of these approaches may require more space but take less time. So we may have to
sacrifice one at the expense of the other. That is, we can say that there is a space-time
exchange between the algorithms. Therefore, if space is our constraint, we should choose a
program that requires less space at the cost of more execution time.

Also, if time is our constraint, then we should choose a program that takes less time to
complete the execution of statements at the expense of more memory. When analyzing
algorithms, we are interested in the average case, the amount of time the program is expected
to take on typical inputs, and in the worst case, the total time required by the program or
algorithm. Here would take the worst possible inputs of this algorithm.

Example:

5.1, Types of Trade-offs:

Lookup tables Vs Recalculation

An algorithm involving a lookup table is an implementation can include the entire


table, which reduces computing time, but increases the amount of memory needed, or it can
compute table entries as needed, increasing computing time, but reducing memory
requirements.

Compressed Vs Un compressed data

The data storage problem can also be solved using space-time compensation
algorithms. If the data is stored uncompressed, it takes up more space, but it takes less time to
access it than if the data is stored compressed (because data compression reduces the amount
of space it takes up, but the decompression algorithm takes time to run). It depends on the
particular instance of the problem, it's handy anyway. There are also rare cases where it is
possible to work directly with compressed data, for example in the case of compressed
bitmap indexes, when working with compression is faster than without compression.

Re Rendering Vs Stored images


In this case, keeping only the SVG source of the vector image and rendering it as a
bitmap each time the page is requested would mean trading time for space; used more time
but less space. Rendering an image on page change and saving the rendered images would
mean trading space for time; uses more space but less time. This technique is more
commonly known as caching.

Smaller code Vs loop unrolling

This technique is typically used to increase the length of the code for each iteration of
the loop, but saves the computation time required to return to the beginning of the loop at the
end of each iteration. The larger code size can be traded for faster program speed when loop
unwinding is applied. Others types are:

● Add and store data


● Access data
● Remove data
● It works as specified
● It is easy to understand and modify
● It is reasonably efficient
● Implementations of ADTs can be changed (e.g., for efficiency) without requiring
changes to the program that uses the ADTs
● ADTs can be reused in future programs

5.2, Example:

Hierarchical tries: slow and compact


A hierarchical trie data structure. The gray pointers are the “next-trie” pointers. The path
traversed by the query algorithms on an incoming packet(000, 010) is shown.

Set-pruning tries: fast and large


Hierarchical tries vs Set-pruning tries ( worst-case )

IV, IMPLEMENTATION:
1, Implement an ADT and algorithm

To solve the problem of finding the shortest path, as suggested above, I will use Dijktra
algorithm to find the shortest path and for ADT, I will use Queue to find the path

2, Unit test / test documentation

Test Test Case Expected Actual Outcome Statu


Cas s
e ID
1 Try to Displays Pass
find the the exact
shortest shortest
path from path result
0 to the
remainin
g vertices

2 Try to Displays Pass


find the the exact
minimum minimum
distance distance
from 0 to result
the rest of
the vertex
3 Check Displays Pass
the the correct
function content that
options in matches the
the selection
program when input
4 Enter Displays Pass
wrong the message
choice "Invalid
selection!"..
.
5 Enter Display the Pass
number 9 message
to exit the "Exit the
program program!"
and exit the
program

3, Source code and evidence

3.1, Vertices.java class:

package DSA_no4;
import java.util.ArrayList;
import java.util.List;

public class Vertices implements Comparable<Vertices> {

private boolean dijkstra_visited;


private String name;
private List<Edges> List;
private double distance = Double.MAX_VALUE;
private Vertices priority;
public Vertices(String name) {
this.name = name;
this.List = new ArrayList<>();
}

public List<Edges> getList() {


return List;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public void setList(List<Edges> List) {


this.List = List;
}

public void addAdjacentVertices(Edges edge) {


this.List.add(edge);
}

public boolean dijkstra_visited() {


return dijkstra_visited;
}

public void setDijkstra_visited(boolean dijkstra_visited) {


this.dijkstra_visited = dijkstra_visited;
}

public Vertices getPriority() {


return priority;
}

public void setPriority(Vertices priority) {


this.priority = priority;
}

public double getDistance() {


return distance;
}

public void setDistance(double distance) {


this.distance = distance;
}

@Override
public String toString() {
return this.name;
}

@Override
public int compareTo(Vertices otherV) {
return Double.compare(this.distance, otherV.getDistance());
}
}

3.2, Edges.java class:

package DSA_no4;

public class Edges {


private double weight;
private Vertices sourceVertices;
private Vertices destinationVertices;

public Edges(double weight, Vertices sourceVertices, Vertices


destinationVertices) {
this.weight = weight;
this.sourceVertices = sourceVertices;
this.destinationVertices = destinationVertices;
}

public double getWeight() {


return weight;
}

public void setWeight(double weight) {


this.weight = weight;
}

public Vertices getSourceVert() {


return sourceVertices;
}

public void setSourceVert(Vertices sourceVert) {


this.sourceVertices = sourceVert;
}

public Vertices getDestinationVertices() {


return destinationVertices;
}

public void setDestinationVertices(Vertices destinationVertices) {


this.destinationVertices = destinationVertices;
}
}

3.3, ShortestPathFind.class:

package DSA_no4;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;

public class ShortestPathFind {


public void ShortestP(Vertices sourceVts) {
sourceVts.setDistance(0);
PriorityQueue<Vertices> priorityQueue = new PriorityQueue<>();
priorityQueue.add(sourceVts);
sourceVts.setDijkstra_visited(true);

while (!priorityQueue.isEmpty()) {
Vertices actualVertex = priorityQueue.poll();
for (Edges edge : actualVertex.getList()) {
Vertices vts = edge.getDestinationVertices();

if (!vts.dijkstra_visited()) {
double newDistance = actualVertex.getDistance()
+ edge.getWeight();
if (newDistance < vts.getDistance()) {
priorityQueue.remove(vts);
vts.setDistance(newDistance);
vts.setPriority(actualVertex);
priorityQueue.add(vts);
}
}
}
actualVertex.setDijkstra_visited(true);
}
}

public List<Vertices> getShortestP(Vertices targetVertex) {


List<Vertices> path = new ArrayList<>();
for (Vertices vertex = targetVertex; vertex != null; vertex =
vertex.getPriority()) {
path.add(vertex);
}
Collections.reverse(path);
return path;
}

3.4, Main.java class:

package DSA_no4;

import java.util.Scanner;

public class Main {

public static void showMenu() {


System.out.println("The program to find the shortest path and the
minimun distance from: ");
System.out.println("1. 0 to 1");
System.out.println("2. 0 to 2");
System.out.println("3. 0 to 3");
System.out.println("4. 0 to 4");
System.out.println("5. 0 to 5");
System.out.println("6. 0 to 6");
System.out.println("7. 0 to 7");
System.out.println("8. 0 to 8");
System.out.println("9. Exit!");
}
public static void main(String[] args) {

Vertices v0 = new Vertices("0");


Vertices v1 = new Vertices("1");
Vertices v2 = new Vertices("2");
Vertices v3 = new Vertices("3");
Vertices v4 = new Vertices("4");
Vertices v5 = new Vertices("5");
Vertices v6 = new Vertices("6");
Vertices v7 = new Vertices("7");
Vertices v8 = new Vertices("8");

v0.addAdjacentVertices(new Edges(5, v0, v1));


v0.addAdjacentVertices(new Edges(3, v0, v2));
v1.addAdjacentVertices(new Edges(4, v1, v3));
v1.addAdjacentVertices(new Edges(2, v1, v4));
v1.addAdjacentVertices(new Edges(6, v1, v5));
v2.addAdjacentVertices(new Edges(5, v2, v4));
v2.addAdjacentVertices(new Edges(7, v2, v5));
v3.addAdjacentVertices(new Edges(8, v3, v6));
v4.addAdjacentVertices(new Edges(7, v4, v6));
v4.addAdjacentVertices(new Edges(6, v4, v7));
v5.addAdjacentVertices(new Edges(5, v5, v7));
v6.addAdjacentVertices(new Edges(8, v6, v8));
v7.addAdjacentVertices(new Edges(7, v7, v8));

ShortestPathFind shortestPathFind = new ShortestPathFind();


shortestPathFind.ShortestP(v0);

int option = -1;


Scanner in = new Scanner(System.in);
do {
showMenu();
System.out.print("Enter your choice:");
option = Integer.parseInt(in.nextLine());
switch(option) {
case 1:
System.out.println("The shortest path from 0 to 1: "
+ shortestPathFind.getShortestP(v1));
System.out.println("The minimun distance from 0 to 1:
" + v1.getDistance());
System.out.println("\n");

break;
case 2:
System.out.println("The shortest path from 0 to 2: "
+ shortestPathFind.getShortestP(v2));
System.out.println("The minimun distance from 0 to 2:
" + v2.getDistance());
System.out.println("\n");
break;
case 3:
System.out.println("The shortest path from 0 to 3: "
+ shortestPathFind.getShortestP(v3));
System.out.println("The minimun distance from 0 to 3:
" + v3.getDistance());
System.out.println("\n");
break;
case 4:
System.out.println("The shortest path from 0 to 4: "
+ shortestPathFind.getShortestP(v4));
System.out.println("The minimun distance from 0 to 4:
" + v4.getDistance());
System.out.println("\n");
break;
case 5:
System.out.println("The shortest path from 0 to 5: "
+ shortestPathFind.getShortestP(v5));
System.out.println("The minimun distance from 0 to 5:
" + v5.getDistance());
System.out.println("\n");
break;
case 6:
System.out.println("The shortest path from 0 to 6: "
+ shortestPathFind.getShortestP(v6));
System.out.println("The minimun distance from 0 to 1:
" + v6.getDistance());
System.out.println("\n");
break;
case 7:
System.out.println("The shortest path from 0 to 7: "
+ shortestPathFind.getShortestP(v7));
System.out.println("The minimun distance from 0 to 7:
" + v7.getDistance());
System.out.println("\n");
break;
case 8:
System.out.println("The shortest path from 0 to 8: "
+ shortestPathFind.getShortestP(v8));
System.out.println("The minimun distance from 0 to 8:
" + v8.getDistance());
System.out.println("\n");
break;
case 9:
System.out.println("Exit the program!");
break;
default:
System.out.println("Invalid selection!");
}
} while (option != 9);
in.close();

}
}

3.5, The result:


Reference:

Cleophas Mulongo, September 19, 2022, The Importance Of Algorithms In Computer


Programming, 28/10/2022:

https://www.technotification.com/2019/02/importance-of-algorithms-programming.html

2021, ENCAPSULATION AND ABSTRACT DATA TYPES, 28/10/2022:

http://www.comscigate.com/cs/IntroSedgewick/30oop/34encapsulation/index.html

Quora, 2021, What's encapsulation, and what are the benefits of using encapsulation?,
28/10/2022:

https://www.quora.com/Whats-encapsulation-and-what-are-the-benefits-of-using-encapsulati
on

Miscellaneous, October 27, 2020, What is FIFO data structure explain with an application?,
28/10/2022:

https://biosidmartin.com/what-is-fifo-data-structure-explain-with-an-application/

Geek for Geek, 01 Sep, 2022, FIFO (First-In-First-Out) approach in Programming,


28/10/2022:

https://www.geeksforgeeks.org/fifo-first-in-first-out-approach-in-programming/

HelloKoding, 21 October 2020, FIFO, Double-Ended and Priority Queue Data Structures
Tutorial with Java Examples, 28/10/2022:

https://hellokoding.com/queue-data-structure/

assignment expert, 2021, The three benefits of using implementation independent data
structure(abstract data structure), 28/10/2022:

https://www.assignmentexpert.com/homework-answers/programming-and-computer-science/
java-jsp-jsf/question-149033

Concept Draw, 2021, Specification and Description Language (SDL), 28/10/2022:

https://www.conceptdraw.com/solution-park/engineering-sdl
VisualParadigm, 2021, What is Specification and Description Language (SDL), 28/10/2022:

https://online.visual-paradigm.com/knowledge/sdl-diagram/what-is-sdl-diagram/

Paradeep Kumar, December 6/2021, Error handling Testing, 28/10/2022:

https://www.h2kinfosys.com/blog/error-handling-testing/

OneStopTesting, 2022, Error handling Testing, 28/10/2022:

http://www.onestoptesting.com/error-handling-testing/

ProfessionalQA, October 17, 2019, Error Handling Testing Technique, 28/10/2022:

https://www.professionalqa.com/error-handling-testing-technique

Geek for Geek, 05 Jun, 2022, What is algorithm and why analysis of it is important?,
28/10/2022:

https://www.geeksforgeeks.org/what-is-algorithm-and-why-analysis-of-it-is-important/

Sunita Kumari, Dec 28, 2020, What is performance analysis in Data Structure and an
Algorithms, 28/10/2022:

https://www.goeduhub.com/11200/what-is-performance-analysis-data-structure-and-algorith
m

Aditya Shukla, 2021, Explanation of Abstract Data Types with Diagram and Example,
28/10/2022:

https://www.tutorialscan.com/data_structure/abstract-data-types/

Bellman Ford's Algorithm, 2021, Bellman Ford's Algorithm.28/10/2022:

https://www.programiz.com/dsa/bellman-ford-algorithm

CS240: Data Structures & Algorithms I, 2021, CS240: Data Structures & Algorithms I,
28/10/2022:

https://www.cpp.edu/~ftang/courses/CS240/lectures/adt.htm.
Encapsulation and Abstract Data Types (ADT), 2021, Encapsulation and Abstract Data
Types, 28/10/2022:

http://www.dba-oracle.com/t_object_encapsulation_abstract.htm.

FACE Prep, 2021, Types of Queue in Data structure | Queue Data structure Introduction and
Operations, 28/10/2022:

https://www.faceprep.in/data-structures/types-of-queue-data-structure/

freeCodeCamp.org, 202, Dijkstra's Shortest Path Algorithm - A Detailed and Visual,


28/10/2022:

https://www.freecodecamp.org/news/dijkstras-shortest-path-algorithm-visual-introduction/

Hello Codies, 2021, Abstract Data type - Definition and it's Importance | Hello Codies,
28/10/2022:

https://www.hellocodies.com/abstract-data-type/

You might also like