Implementing and Assessing Data Structures and Algorithms in Java - Prof. Pphạm, Exams of Molecular Chemistry

A comprehensive guide to implementing and assessing data structures and algorithms in java. It covers the implementation of a queue and a stack using adt (array) and demonstrates their functionality through a chat box simulation. The document also delves into the concept of big o notation and its application in measuring the efficiency of algorithms. It further explores the benefits and trade-offs of using adt in design and development, providing insights into the importance of abstraction, modularity, and reusability. Finally, it analyzes the time and space complexity of the implemented algorithms, highlighting the effectiveness of the chosen approach.

Typology: Exams

2023/2024

Uploaded on 10/24/2024

shanthi_48
shanthi_48 🇺🇸

4.8

(36)

891 documents

1 / 7

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Implementing and Assessing Data
Structures and Algorithms
Implementing Complex Data Structures and
Algorithms
1. Implement ADT & Algorithms
1.1 Description of the Application
The system must be designed with ADT (Abstract Data Types) and
algorithms for two data structures - a queue and a stack. A demo version
must be run with messages of up to 250 characters. The demo should
showcase the important operations of these data structures. Although this is
a demo version, errors must be handled with exceptions, and some tests
must be performed to demonstrate the correctness of the algorithms and
operations.
1.2 Implement the Program (P4)
To develop the data structures and algorithms, I have chosen to use ADT
(Array) and implement them in the Java programming language. Here is the
code to implement the algorithms:
Queue.java ```java public class Queue { private int total = 0; private
String[] queue; private int rear; private int front;
public Queue() {
queue = new String[25];
rear = 0;
front = -1;
}
public void enqueue(String s) {
if (total < 25) {
total++;
front++;
queue[front] = s;
}
}
public String dequeue() {
if (total > 0) {
total--;
String temp = queue[rear++];
if (rear == queue.length) {
rear = 0;
pf3
pf4
pf5

Partial preview of the text

Download Implementing and Assessing Data Structures and Algorithms in Java - Prof. Pphạm and more Exams Molecular Chemistry in PDF only on Docsity!

Implementing and Assessing Data

Structures and Algorithms

Implementing Complex Data Structures and

Algorithms

1. Implement ADT & Algorithms

1.1 Description of the Application

The system must be designed with ADT (Abstract Data Types) and algorithms for two data structures - a queue and a stack. A demo version must be run with messages of up to 250 characters. The demo should showcase the important operations of these data structures. Although this is a demo version, errors must be handled with exceptions, and some tests must be performed to demonstrate the correctness of the algorithms and operations.

1.2 Implement the Program (P4)

To develop the data structures and algorithms, I have chosen to use ADT (Array) and implement them in the Java programming language. Here is the code to implement the algorithms:

Queue.java ```java public class Queue { private int total = 0; private String[] queue; private int rear; private int front;

public Queue() { queue = new String[25]; rear = 0; front = -1; }

public void enqueue(String s) { if (total < 25) { total++; front++; queue[front] = s; } }

public String dequeue() { if (total > 0) { total--; String temp = queue[rear++]; if (rear == queue.length) { rear = 0;

front = -1; } return temp; } return ""; }

public boolean isEmpty() { return total == 0; }

public boolean isFull() { return total == queue.length; }

} ```

Stack.java ```java public class Stack { private String[] stack; private int index; private int total = 0;

public Stack() { stack = new String[25]; index = -1; }

public void push(String s) { if (index < 24) { total++; stack[++index] = s; } }

public String pop() { if (index >= 0) { total--; return stack[index--]; } return ""; }

public boolean isEmpty() { return total == 0; }

public boolean isFull() { return total == 25; }

} ```

Application.java ```java import java.util.Random;

Assessing the Effectiveness of Data Structures

and Algorithms

2.1 Big O (P6)

Big O Notation is a way to measure an algorithm's efficiency. It measures the time it takes to run a function as the input grows, or in other words, how well the function scales.

To measure the Time and Space Complexity, we use Asymptotic Analysis. Asymptotic Analysis is the big idea that handles the issues in analyzing algorithms. In Asymptotic Analysis, we evaluate the performance of an algorithm in terms of input size (we don't measure the actual running time). We calculate how the time (or space) taken by an algorithm increases with the input size.

For example, when considering the search problem of searching for a given item in a sorted array, one way to search is Linear Search (order of growth is linear), and the other way is Binary Search (order of growth is logarithmic). Asymptotic Analysis can help us understand how these algorithms scale with input size, even if one is running on a faster computer than the other.

The commonly used asymptotic notations to calculate the running time complexity of an algorithm are:

Ο Notation (Big Oh Notation, Ο) : The notation Ο(n) is the formal way to express the upper bound of an algorithm's running time. It measures the worst-case time complexity or the longest amount of time an algorithm can possibly take to complete.

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

θ Notation (Theta Notation, θ) : The notation θ(n) is the formal way to express both the lower bound and the upper bound of an algorithm's running time.

In this program, we will use asymptotic analysis to assess the effectiveness of the Transfer function algorithm:

while (n < source.Length && n < messageLimit) //O(n^2) { while (myQueue.Count <= maxBuffer) { if (n == messageLimit) { break; } myQueue.Enqueue(source[n]); n++; } ... }

In this program, the complexity of the algorithm is O(n^2). So, this algorithm is acceptable, but Asymptotic Analysis is not perfect, and it is the best way available for analyzing algorithms.

2.2 Measuring Efficiency (P7)

There are two main ways to measure the efficiency of an algorithm:

Time Complexity : This measures the amount of time an algorithm takes to run as a function of the size of its input. The time complexity is usually expressed using Big O notation.

Space Complexity : This measures the amount of memory an algorithm uses as a function of the size of its input. The space complexity is also usually expressed using Big O notation.

For example, let's consider the efficiency of the enqueue and dequeue operations in the Queue class:

enqueue() : - Time Complexity: O(1) - The operation takes a constant amount of time, regardless of the size of the queue. - Space Complexity: O(1)

  • The operation uses a constant amount of memory, regardless of the size of the queue.

dequeue() : - Time Complexity: O(1) - The operation takes a constant amount of time, regardless of the size of the queue. - Space Complexity: O(1)

  • The operation uses a constant amount of memory, regardless of the size of the queue.

These efficiency measures can be used to compare the performance of different algorithms and data structures, and to make informed decisions about which ones to use in a given scenario.

3. Evaluating the Use of ADT in Design and Development

The use of ADT (Abstract Data Types) in design and development has several benefits:

Abstraction : ADTs provide a level of abstraction, allowing developers to focus on the high-level behavior of the data structure without worrying about the underlying implementation details.

Modularity : ADTs promote modular design, as they can be implemented and tested independently of the rest of the system.

Reusability : ADTs can be reused across multiple projects or components, reducing development time and effort.

Flexibility : ADTs can be easily modified or replaced with alternative implementations without affecting the rest of the system.

Efficiency : ADTs can be designed and optimized for specific use cases, improving the overall efficiency of the system.

Maintainability : ADTs help to improve the maintainability of the codebase, as the implementation details are encapsulated and changes can be made without affecting the rest of the system.

The .NET GC.GetTotalMemory method was used to measure the memory usage of the algorithm.

Abstract Data Types (ADTs)

Data structures are designed to store ordered data in memory, allowing various operations to be performed efficiently. The implementation of a data structure usually requires writing a set of procedures that create and manipulate instances of that structure. The efficiency of a data structure cannot be analyzed separately from the operations performed on it, which motivates the concept of an abstract data type (ADT). An ADT is a data structure defined indirectly by the operations that may be performed on it and the mathematical properties of those operations, including their space and time cost. Understanding ADTs and their implementation can help in designing and analyzing the performance of real-world programs.