Data Structures For First Year
Data Structures For First Year
and Algorithms
By
M.Rajanikanth
Lecturer
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.
To structure the data in memory, 'n' number of algorithms were proposed, and all these
algorithms are known as Abstract data types. These abstract data types are the set of
rules.
The primitive data structures are primitive data types. The int, char, float, double, and
pointer are the primitive data structures that can hold a single value.
Non-Primitive Data structure
The arrangement of data in a sequential manner is known as a linear data structure. The data
structures used for this purpose are Arrays, Linked list, Stacks, and Queues. In these data
structures, one element is connected to only one another element in a linear form.
When one element is connected to the 'n' number of elements known as a non-linear
data structure. The best example is trees and graphs. In this case, the elements are
arranged in a random manner.
We will discuss the above data structures in brief in the coming topics. Now, we will see
the common operations that we can perform on these data structures.
o Static data structure: It is a type of data structure where the size is allocated at
the compile time. Therefore, the maximum size is fixed.
o Dynamic data structure: It is a type of data structure where the size is allocated
at the run time. Therefore, the maximum size is flexible.
Major Operations
The major or the common operations that can be performed on the data structures are:
As the different data structures can be implemented in a particular ADT, but the
different implementations are compared for time and space. For example, the Stack ADT
can be implemented by both Arrays and linked list. Suppose the array is providing time
efficiency while the linked list is providing space efficiency, so the one which is the best
suited for the current user's requirements will be selected.
Linear Data Structures: A data structure is called linear if all of its elements are
arranged in the linear order. In linear data structures, the elements are stored in non-
hierarchical way where each element has the successors and predecessors except the
first and last element.
Types of Linear Data Structures are given below:
Arrays: An array is a collection of similar type of data items and each data item is called
an element of the array. The data type of the element may be any valid data type like
char, int, float or double.
The elements of array share the same variable name but each one carries a different
index number known as subscript. The array can be one dimensional, two dimensional
or multidimensional.
Linked List: Linked list is a linear data structure which is used to maintain a list in the
memory. It can be seen as the collection of nodes stored at non-contiguous memory
locations. Each node of the list contains a pointer to its adjacent node.
Stack: Stack is a linear list in which insertion and deletions are allowed only at one end,
called top.
A stack is an abstract data type (ADT), can be implemented in most of the programming
languages. It is named as stack because it behaves like a real-world stack, for example: -
piles of plates or deck of cards etc.
Queue: Queue is a linear list in which elements can be inserted only at one end
called rear and deleted only at the other end called front.
It is an abstract data structure, similar to stack. Queue is opened at both end therefore it
follows First-In-First-Out (FIFO) methodology for storing the data items.
Non Linear Data Structures: This data structure does not form a sequence i.e. each
item or element is connected with two or more other items in a non-linear arrangement.
The data elements are not arranged in sequential structure.
Trees: Trees are multilevel data structures with a hierarchical relationship among its
elements known as nodes. The bottommost nodes in the herierchy are called leaf
node while the topmost node is called root node. Each node contains pointers to point
adjacent nodes.
Tree data structure is based on the parent-child relationship among the nodes. Each
node in the tree can have more than one children except the leaf nodes whereas each
node can have atmost one parent except the root node. Trees can be classfied into
many categories which will be discussed later in this tutorial.
If the size of data structure is n then we can only insert n-1 data elements into it.
6) Merging: When two lists List A and List B of size M and N respectively, of similar type
of elements, clubbed or joined to produce the third list, List C of size (M+N), then this
process is called merging
What is an Algorithm?
An algorithm is a process or a set of rules required to perform calculations or some
other problem-solving operations especially by a computer. The formal definition of an
algorithm is that it contains the finite set of instructions which are being carried in a
specific order to perform the specific task. It is not the complete program or code; it is
just a solution (logic) of a problem, which can be represented either as an informal
description using a Flowchart or Pseudocode.
Characteristics of an Algorithm
The following are the characteristics of an algorithm:
o Input: An algorithm has some input values. We can pass 0 or some input value to an
algorithm.
o Output: We will get 1 or more output at the end of an algorithm.
o Unambiguity: An algorithm should be unambiguous which means that the instructions
in an algorithm should be clear and simple.
o Finiteness: An algorithm should have finiteness. Here, finiteness means that the
algorithm should contain a limited number of instructions, i.e., the instructions should be
countable.
o Effectiveness: An algorithm should be effective as each instruction in an algorithm
affects the overall process.
o Language independent: An algorithm must be language-independent so that the
instructions in an algorithm can be implemented in any of the languages with the same
output.
Dataflow of an Algorithm
o Problem: A problem can be a real-world problem or any instance from the real-world
problem for which we need to create a program or the set of instructions. The set of
instructions is known as an algorithm.
o Algorithm: An algorithm will be designed for a problem which is a step by step
procedure.
o Input: After designing an algorithm, the required and the desired inputs are provided to
the algorithm.
o Processing unit: The input will be given to the processing unit, and the processing unit
will produce the desired output.
o Output: The output is the outcome or the result of the program.
Step 2: Squeeze the lemon as much you can and take out its juice in a container.
Step 5: When sugar gets dissolved, add some water and ice in it.
The above real-world can be directly compared to the definition of the algorithm. We
cannot perform the step 3 before the step 2, we need to follow the specific order to
make lemon juice. An algorithm also says that each and every instruction should be
followed in a specific order to perform a specific task.
Now we will look an example of an algorithm in programming.
The following are the steps required to add two numbers entered by the user:
Step 1: Start
Step 4: Add the values of a and b and store the result in the sum variable, i.e., sum=a+b.
Step 6: Stop
Factors of an Algorithm
The following are the factors that we need to consider for designing an algorithm:
o Modularity: If any problem is given and we can break that problem into small-
small modules or small-small steps, which is a basic definition of an algorithm, it
means that this feature has been perfectly designed for the algorithm.
o Correctness: The correctness of an algorithm is defined as when the given inputs
produce the desired output, which means that the algorithm has been designed
algorithm. The analysis of an algorithm has been done correctly.
o Maintainability: Here, maintainability means that the algorithm should be
designed in a very simple structured way so that when we redefine the algorithm,
no major change will be done in the algorithm.
o Functionality: It considers various logical steps to solve the real-world problem.
o Robustness: Robustness means that how an algorithm can clearly define our
problem.
o User-friendly: If the algorithm is not user-friendly, then the designer will not be
able to explain it to the programmer.
o Simplicity: If the algorithm is simple then it is easy to understand.
o Extensibility: If any other algorithm designer or programmer wants to use your
algorithm then it should be extensible.
Importance of Algorithms
Issues of Algorithms
The following are the issues that come while designing an algorithm:
Approaches of Algorithm
The following are the approaches used after considering both the theoretical and
practical importance of designing an algorithm:
o Brute force algorithm: The general logic structure is applied to design an
algorithm. It is also known as an exhaustive search algorithm that searches all the
possibilities to provide the required solution. Such algorithms are of two types:
1. Optimizing: Finding all the solutions of a problem and then take out the
best solution or if the value of the best solution is known then it will
terminate if the best solution is known.
2. Sacrificing: As soon as the best solution is found, then it will stop.
o Divide and conquer: It is a very implementation of an algorithm. It allows you to
design an algorithm in a step-by-step variation. It breaks down the algorithm to
solve the problem in different methods. It allows you to break down the problem
into different methods, and valid output is produced for the valid input. This valid
output is passed to some other function.
o Greedy algorithm: It is an algorithm paradigm that makes an optimal choice on
each iteration with the hope of getting the best solution. It is easy to implement
and has a faster execution time. But, there are very rare cases in which it provides
the optimal solution.
o Dynamic programming: It makes the algorithm more efficient by storing the
intermediate results. It follows five different steps to find the optimal solution for
the problem:
1. It breaks down the problem into a subproblem to find the optimal
solution.
2. After breaking down the problem, it finds the optimal solution out of these
subproblems.
3. Stores the result of the subproblems is known as memorization.
4. Reuse the result so that it cannot be recomputed for the same
subproblems.
5. Finally, it computes the result of the complex program.
o Branch and Bound Algorithm: The branch and bound algorithm can be applied
to only integer programming problems. This approach divides all the sets of
feasible solutions into smaller subsets. These subsets are further evaluated to find
the best solution.
o Randomized Algorithm: As we have seen in a regular algorithm, we have
predefined input and required output. Those algorithms that have some defined
set of inputs and required output, and follow some described steps are known as
deterministic algorithms. What happens that when the random variable is
introduced in the randomized algorithm?. In a randomized algorithm, some
random bits are introduced by the algorithm and added in the input to produce
the output, which is random in nature. Randomized algorithms are simpler and
efficient than the deterministic algorithm.
o Backtracking: Backtracking is an algorithmic technique that solves the problem
recursively and removes the solution if it does not satisfy the constraints of a
problem.
Algorithm Complexity
The performance of the algorithm can be measured in two factors:
1. sum=0;
2. // Suppose we have to calculate the sum of n numbers.
3. for i=1 to n
4. sum=sum+i;
5. // when the loop ends then sum holds the sum of the n numbers
6. return sum;
In the above code, the time complexity of the loop statement will be atleast n, and if the
value of n increases, then the time complexity also increases. While the complexity of
the code, i.e., return sum will be constant as its value is not dependent on the value of n
and will provide the result in one step only. We generally consider the worst-time
complexity as it is the maximum time taken for any given input size.
Auxiliary space: The extra space required by the algorithm, excluding the input size, is
known as an auxiliary space. The space complexity considers both the spaces, i.e.,
auxiliary space, and space used by the input.
So,
Types of Algorithms
The following are the types of algorithm:
o Search Algorithm
o Sort Algorithm
Search Algorithm
On each day, we search for something in our day to day life. Similarly, with the case of
computer, huge data is stored in a computer that whenever the user asks for any data
then the computer searches for that data in the memory and provides that data to the
user. There are mainly two techniques available to search the data in an array:
o Linear search
o Binary search
Linear Search
Linear search is a very simple algorithm that starts searching for an element or a value
from the beginning of an array until the required element is not found. It compares the
element to be searched with all the elements in an array, if the match is found, then it
returns the index of the element else it returns -1. This algorithm can be implemented
on the unsorted list.
Binary Search
A Binary algorithm is the simplest algorithm that searches the element very quickly. It is
used to search the element from the sorted list. The elements must be stored in
sequential order or the sorted manner to implement the binary algorithm. Binary search
cannot be implemented if the elements are stored in a random manner. It is used to find
the middle element of the list.
Sorting Algorithms
Sorting algorithms are used to rearrange the elements in an array or a given data
structure either in an ascending or descending order. The comparison operator decides
the new order of the elements.
Array
Definition
o Arrays are defined as the collection of similar type of data items stored at contiguous
memory locations.
o Arrays are the derived data type in C programming language which can store the
primitive type of data such as int, char, double, float, etc.
o Array is the simplest data structure where each data element can be randomly accessed
by using its index number.
o For example, if we want to store the marks of a student in 6 subjects, then we don't need
to define different variable for the marks in different subject. instead of that, we can
define an array which can store the marks in each subject at a the contiguous memory
locations.
1. int arr[10]; char arr[10]; float arr[5]
In the following example, we have marks of a student in six different subjects. The
problem intends to calculate the average of all the marks of the student.
In order to illustrate the importance of array, we have created two programs, one is
without using array and other involves the use of array to store marks.
1. #include <stdio.h>
2. void main ()
3. {
4. int marks_1 = 56, marks_2 = 78, marks_3 = 88, marks_4 = 76, marks_5 = 56, m
arks_6 = 89;
5. float avg = (marks_1 + marks_2 + marks_3 + marks_4 + marks_5 +marks_6) / 6
;
6. printf(avg);
7. }
1. #include <stdio.h>
2. void main ()
3. {
4. int marks[6] = {56,78,88,76,56,89);
5. int i;
6. float avg;
7. for (i=0; i<6; i++ )
8. {
9. avg = avg + marks[i];
10. }
11. printf(avg);
12. }
Advantages of Array
o Array provides the single name for the group of variables of the same type therefore, it is
easy to remember the name of all the elements of an array.
o Traversing an array is a very simple process, we just need to increment the base address
of the array in order to visit each element one by one.
o Any element in the array can be directly accessed by using the index.
1. 0 (zero - based indexing) : The first element of the array will be arr[0].
2. 1 (one - based indexing) : The first element of the array will be arr[1].
3. n (n - based indexing) : The first element of the array can reside at any random index
number.
In the following image, we have shown the memory allocation of an array arr of size 5.
The array follows 0-based indexing approach. The base address of the array is 100th
byte. This will be the address of arr[0]. Here, the size of int is 4 bytes therefore each
element will take 4 bytes in the memory.
In 0 based indexing, If the size of an array is n then the maximum index number, an
element can have is n-1. However, it will be n if we use 1 based indexing.
Address of any element of a 1D array can be calculated by using the following formula:
1. Byte address of element A[i] = base address + size * ( i - first index)
Example :
https://www.javatpoint.com/data-structure-asymptotic-analysis