Module 1: Introduction to Data Structure and Algorithm What is Data Structure and Algorithm? In computer programming, a data structure is a predefined format for efficiently storing, accessing, and processing data in a computer program. Some data structures are a programming language built-in component, and others may require the inclusion of a library or module before the structure can be used. Data structure is defined as an arrangement of data in memory locations to represent values of the carrier set of an abstract data type. Different structures are best suited to different kinds of applications in the computer. Others are even highly specialized to specific tasks. There are two types of data structure available for the programming purpose: Primitive data structure Non-primitive data structure Primitive data structure Primitive data structure is a data structure that can hold a single value in a specific location whereas the non-linear data structure can hold multiple values either in a contiguous location or random locations. The examples of primitive data structure are float, character, integer and pointer. The value to the primitive data structure is provided by the programmer. The following are the seven primitive data structures: Integer: The integer data type contains the numeric values. It contains the whole numbers that can be either negative or positive. When the range of integer data type is not large enough then in that case, we can use long. Float: The float is a data type that can hold decimal values. When the precision of decimal value increases then the Double data type is used. Boolean: It is a data type that can hold either a True or a False value. It is mainly used for checking the condition. Character: It is a data type that can hold a single character value both uppercase and lowercase such as 'A' or 'a'. Double: A double-precision floating-point uses twice the number of bytes of a standard float, providing approximately double the precision. Pointer: A pointer is a special value that refers to a memory location where a data object is stored. Fixed Point: A numeric value with a whole number and fractional component, similar to a floating-point number, but with a preset level of precision. Non-primitive data structure The non-primitive data structure is a kind of data structure that can hold multiple values either in a contiguous or random location. The non-primitive data types are defined by the programmer. The non-primitive data structure is further classified into two categories, i.e., linear and non-linear data structure. In case of linear data structure, the data is stored in a sequence, i.e., one data after another data. When we access the data from the linear data structure, we just need to start from one place and will find other data in a sequence. The following are the types of linear data structure: Array: An array is a data structure that can hold the elements of same type. It cannot contain the elements of different types like integer with character. The commonly used operation in an array is insertion, deletion, traversing, searching. For example: int a[6] = {1,2,3,4,5,6}; The above example is an array that contains the integer type elements stored in a contiguous manner. String: String is defined as an array of characters. Nonlinear data structures however, are data structures in which data items are not arranged in a sequence. The following are the types of nonlinear data structure: Tree: A tree can be defined as a finite set of data items (nodes) in which data items are arranged in branches and sub-branches according to requirements. It represent the hierarchical relationship between various elements and consists of nodes connected by an edge, the node represented by a circle and edge lives connecting to the circle. Graph: Graph is a collection of nodes (Information) and connecting edges (Logical relation) between nodes. The data structure is not any programming language like C, C++, java, etc. It is a set of algorithms that we can use in any programming language to structure the data in the memory. An algorithm can be defined as a finite set of steps, which has to be followed while carrying out a particular problem. It is nothing but a process of executing actions step by step. Have you ever baked or cooked something? One of the most obvious examples of an algorithm is a recipe. It's a finite list of instructions used to perform a task. For example, if you were to follow the algorithm to create brownies from a box mix, you would follow the three to five step process written on the back of the box. Very often, the order of the steps that are given can make a big difference. Suppose we were to reorder the steps of the recipe on the back of the brownie box and told somebody to put the brownies in the oven for 22 minutes before we told them to preheat the oven. That would be silly! That's why the ordering of the steps is very important. It is a distinct computational procedure that takes input as a set of values and results in the output as a set of values by solving the problem. More precisely, an algorithm is correct, if, for each input instance, it gets the correct output and gets terminated. It unravels the computational problems to output the desired result. An algorithm can be described by incorporating a natural language such as English, Computer language, or a hardware language. Ways of Writing an Algorithm 1. English-Like Algorithm An algorithm can be written in many ways. It can be written in simple English but this method also has some demerits. Natural language can be ambiguous and therefore lack the characteristic of being definite. Each step of an algorithm should be clear and shouldn't have more than one meaning. English language-like algorithms are not considered good for most of the tasks. Example: Step 1: Start Step 2: Create a variable to receive the user’s email address. Step 3: Clear the variable in case it’s not empty. Step 4: Ask the user for an email address. Step 5: Store the response in the variable. Step 6: Checked the stored response to see if it is a valid email address. Step 7: Not valid? GO back to Step 3. Step 8: End 2. Flowchart Flowcharts pictorially depict a process. It shows steps in sequential order and is widely used in presenting the flow of algorithms, workflow or processes. Typically, a flowchart shows the steps as boxes of various kinds, and their order by connecting them with arrows. Example: 3. Pseudocode Pseudocode refers to an informal high-level description of the operating principle of a computer program or other algorithm. It uses structural conventions of a standard programming language intended for human reading rather than the machine reading. Example: Step 1 – START Step 2 − read a & b Step 3 − c ← a + b Step 4 − display c Step 5 – STOP 4. Programming languages Once we've planned our algorithm, whether in natural language, flow charts, pseudocode, or a combination, it's time to turn it into running code. Example: public class MyClass { public static void main(String[]args) { System.out.print("Hello world!"); } } Characteristics of Algorithm 1. Clear and Unambiguous: Algorithm should be clear and unambiguous. Each of its steps should be clear in all aspects and must lead to only one meaning. 2. Well-Defined Inputs: If an algorithm says to take inputs, it should be well-defined inputs. 3. Well-Defined Outputs: The algorithm must clearly define what output will be yielded and it should be well-defined as well. 4. Finiteness: The algorithm must be finite, i.e. it should not end up in an infinite loops or similar. 5. Feasible: The algorithm must be simple, generic and practical, such that it can be executed upon the availability of the resources. 6. Language Independent: The Algorithm designed must be language-independent, i.e. it must be just plain instructions that can be implemented in any language, and yet the output will be same, as expected. Let us first take an example of a real-life situation for creating algorithm. Here is the algorithm for going to the market to purchase a pen. Step 1: Start Step 2: Get dressed to go to the market. Step 3: Check your wallet for the money. Step 4: If there is no money in the wallet, replenish it. Step 5: Go to the shop. Step 6: Ask for your favourite brand of pen. Step 7: If pen is available, go to step 8 else go to step 11. Step 8: Give money to the shopkeeper. Step 9: Keep the purchased pen safely. Step 10: Go back home. Step 11: Ask for any other brand of pen. Step 12: Go to step 8 How to Design an Algorithm? There are no well-defined standards for writing algorithms. Rather, it is problem and resource dependent. Algorithms are never written to support a particular programming code. As we know that all programming languages share basic code constructs like loops (do, for, while), flow-control (if-else), etc. These common constructs can be used to write an algorithm. We write algorithms in a step-by-step manner. Algorithm writing is a process and is executed after the problem domain is well-defined. That is, we should know the problem domain, for which we are designing a solution. Steps in designing an algorithm. 1. Know the problem that is to be solved by the algorithm. 2. Think of the constraints that must be considered while solving the problem. 3. An input must be taken to solve the problem. 4. Provide a solution to the problem and its constraints. 5. An output is to be expected when the problem is solved. Example 1: Design an algorithm to add two numbers and display the result. A. Fulfilling the pre-requisites 1. The problem that is to be solved by this algorithm: Add 2 numbers and display the result. 2. The constraints of the problem that must be considered while solving the problem: The numbers must contain only digits and no other characters. 3. The input to be taken to solve the problem: The two numbers to be added. 4. The solution to this problem and its constraints: The solution consists of adding the two integers. It can be done with the help of ‘+’ operator. 5. The output to be expected when the problem is solved: The sum of the two numbers taken from the input. B. Designing the algorithm Step 1 – START Step 2 − declare three integers a, b & c Step 3 − read the values of a & b Step 4 − add the values of a & b Step 5 − assign the output of step 4 to c Step 6 − print c Step 7 – STOP Algorithms tell the programmers how to code the program. Alternatively, the algorithm can be written as − Step 1 – START Step 2 − read a & b Step 3 − c ← a + b Step 4 − display c Step 5 – STOP In design and analysis of algorithms, usually the second method is used to describe an algorithm. It makes it easy for the analyst to analyze the algorithm ignoring all unwanted definitions. He can observe what operations are being used and how the process is flowing. Writing step numbers, is optional and we use the following symbol for different operations: ‘+’ for Addition ‘-’ for Subtraction ‘*’ for Multiplication ‘/’ for Division and ‘←’ for assignment. For example A ← X*3 means A will have a value of X*3. The following guidelines must also be followed while developing an algorithm: 1. An algorithm will be enclosed by START (or BEGIN) and STOP (or END). 2. To accept data from user, generally used statements are INPUT, READ, GET or OBTAIN. 3. To display result or any message, generally used statements are PRINT, DISPLAY, or WRITE. 4. Generally, COMPUTE or CALCULATE is used while describing mathematical expressions and based on situation relevant operators can be used. We design an algorithm to get a solution of a given problem. There may be more than one way to solve a problem, so there may be more than one algorithm for a problem. The next step is to analyse those proposed solution algorithms and implement the best suitable solution. C. Testing the algorithm by implementing it public class Test { public static void main (String[] args){ int a, b, c; a = 5; b = 5; c = a+b; System.out.println(c); } } public class Test { public static void main (String[] args){ int a = 5, b = 5; int c = a+b; System.out.println(c); } } The solution to an algorithm can be or cannot be more than one. It means that while implementing the algorithm, there can be more than one method to implement it. Let's follow another real life algorithm example to help you get an understanding of the algorithm concept. Let's say that you have a friend arriving at the airport, and your friend needs to get from the airport to your house. Here are four different algorithms that you might give your friend for getting to your home: The taxi algorithm: 1. Go to the taxi stand. 2. Get in a taxi. 3. Give the driver my address. The call-me algorithm: 1. When your plane arrives, call my cell phone. 2. Meet me outside baggage claim. The rent-a-car algorithm: 1. Take the shuttle to the rental car place. 2. Rent a car. 3. Follow the directions to get to my house. The bus algorithm: 1. Outside baggage claim, catch bus number 70. 2. Transfer to bus 14 on Main Street. 3. Get off on Elm streets. 4. Walk two blocks north to my house. All four of these algorithms accomplish exactly the same goal, but each algorithm does it in completely different way. Each algorithm also has a different cost and a different travel time. Taking a taxi, for example, is probably the fastest way, but also the most expensive. Taking the bus is definitely less expensive, but a whole lot slower. You choose the algorithm based on the circumstances. Now let us take some more exercises to develop an algorithm for some simple problems: Example 2: Design an algorithm to find the area of a circle. A. Fulfilling the pre-requisites 1. 2. 3. 4. Problem: Find the area of a circle. Constraints: The radius must contain only digits and no other characters. Input: Radius of the circle. Solution: The solution consists of multiplying PI to radius2 or radius*radius. It can be done with the help of ‘*’ operator. 5. Output: The area of the circle taken from the input. B. Designing the algorithm Step1: Start Step2: Read the radius of the circle Step3: Area ← PI*radius*radius // calculation of area Step4: Print Area Step5: Stop C. Testing the algorithm by implementing it import java.lang.Math; public class MyFirst { public static void main (String[] args){ float radius = 10.5f; double area = Math.PI*radius*radius; System.out.println("The area of a the circle is "+area); } } Example 3: Design an algorithm to convert a temperature from Fahrenheit to Celsius. A. Fulfilling the pre-requisites 1. 2. 3. 4. Problem: Convert temperature in Fahrenheit to Celcius. Constraints: The radius must contain only digits and no other characters. Input: Temperature in Fahrenheit. Solution: The solution must consists a formula of Celcius = 5/9 *(F-32). It can be done with the help of ‘*’, ‘-’, and ‘/’ operators. 5. Output: Temperature in Celcius. B. Designing the algorithm Step1: Start Step 2: Read Temperature in Fahrenheit Step 3: Celsius ← 5/9*(Fahrenheit -32) Step 4: Print Temperature in Celsius Step5: Stop C. Testing the algorithm by implementing it public class MyFirst { public static void main (String[] args){ float fahrenheit = 32.0f; float celcius = 5/9 *(fahrenheit-32); System.out.println(celcius); } }