Data Structures Module 1
Data Structures Module 1
Ashwini S
Assistant Professor
Ashwini S Data Structures with C++ 07-11-2023
2 AGENDA
7 1. ARRAY:
8 2. LINKED LISTS:
• Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not
stored at a contiguous location; the elements are linked using pointers.
Ashwini S Data Structures with C++ 07-11-2023
9 3. STACK:
• Stack is a linear data structure which follows a particular order in which the operations are performed.
• The order may be LIFO(Last In First Out) or FILO(First In Last Out). In stack, all insertion and deletion
are permitted at only one end of the list.
Ashwini S Data Structures with C++ 07-11-2023
10 STACK OPERATIONS:
11 4. QUEUE:
12 QUEUE OPERATIONS:
16 USE CASES
19 WHAT IS AN ALGORITHM?
1. Algorithms are necessary for solving complex problems efficiently and effectively.
2. They help to automate processes and make them more reliable, faster, and easier to
perform.
3. Algorithms also enable computers to perform tasks that would be difficult or
impossible for humans to do manually.
4. They are used in various fields such as mathematics, computer science, engineering,
finance, and many others to optimize processes, analyze data, make predictions, and
provide solutions to problems.
Ashwini S Data Structures with C++ 07-11-2023
22
• Clear and Unambiguous: The algorithm should be unambiguous. Each of its steps should be clear in all
aspects and must lead to only one meaning.
• Well-Defined Inputs: If an algorithm says to take inputs, it should be well-defined inputs. It may or may not
take input.
• Well-Defined Outputs: The algorithm must clearly define what output will be yielded and it should be well-
defined as well. It should produce at least 1 output.
• Finite-ness: The algorithm must be finite, i.e. it should terminate after a finite time.
• Feasible: The algorithm must be simple, generic, and practical, such that it can be executed with the available
resources. It must not contain some future technology or anything.
• 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 the same, as expected.
Ashwini S Data Structures with C++ 07-11-2023
23
24 TYPES OF ALGORITHMS:
There are several types of algorithms available. Some important algorithms are:
1. Brute Force Algorithm: It is the simplest approach to a problem. A brute force algorithm is the first approach that
comes to finding when we see a problem.
2. Recursive Algorithm: A recursive algorithm is based on recursion. In this case, a problem is broken into several sub-
parts and called the same function again and again.
3. Backtracking Algorithm: The backtracking algorithm builds the solution by searching among all possible solutions.
Using this algorithm, we keep on building the solution following criteria. Whenever a solution fails we trace back to the
failure point build on the next solution and continue this process till we find the solution or all possible solutions are
looked after.
4. Searching Algorithm: Searching algorithms are the ones that are used for searching elements or groups of elements
from a particular data structure. They can be of different types based on their approach or the data structure in which the
element should be found.
Ashwini S Data Structures with C++ 07-11-2023
25
5. Sorting Algorithm: Sorting is arranging a group of data in a particular manner according to the requirement. The
algorithms which help in performing this function are called sorting algorithms. Generally sorting algorithms are used to sort
groups of data in an increasing or decreasing manner.
6. Hashing Algorithm: Hashing algorithms work similarly to the searching algorithm. But they contain an index with a key
ID. In hashing, a key is assigned to specific data.
7. Divide and Conquer Algorithm: This algorithm breaks a problem into sub-problems, solves a single sub-
problem, and merges the solutions to get the final solution. It consists of the following three steps: Divide, Solve,
Combine
8. Greedy Algorithm: In this type of algorithm, the solution is built part by part. The solution for the next part is built
based on the immediate benefit of the next part. The one solution that gives the most benefit will be chosen as the
solution for the next part.
Ashwini S Data Structures with C++ 07-11-2023
27
Ashwini S Data Structures with C++ 07-11-2023
28
Ashwini S Data Structures with C++ 07-11-2023
29 PERFORMANCE ANALYSIS
• When several algorithms can be designed for the solution of a problem, there arises the
need to determine which among them is the best.
• The efficiency of a program or an algorithm is measured by computing its time and/or space
complexities.
• The time complexity of an algorithm is a function of the running time of the algorithm.
• The space complexity is a function of the space required by it to run to completion. The
time complexity is therefore given in terms of frequency count.
• Frequency count is basically a count denoting number of times a statement execution
Ashwini S Data Structures with C++ 07-11-2023
30 ASYMPTOTIC ANALYSIS
• The efficiency of an algorithm depends on the amount of time, storage and other resources
required to execute the algorithm.
• The efficiency is measured with the help of asymptotic notations.
• An algorithm may not have the same performance for different types of inputs. With the
increase in the input size, the performance will change.
• The study of change in performance of the algorithm with the change in the order of the
input size is defined as asymptotic analysis.
Ashwini S Data Structures with C++ 07-11-2023
31 ASYMPTOTIC NOTATIONS
• Asymptotic notations are the mathematical notations used to describe the running time
of an algorithm when the input tends towards a particular value or a limiting value.
• For example: In bubble sort, when the input array is already sorted, the time taken by the
algorithm is linear i.e. the best case.
• But, when the input array is in reverse condition, the algorithm takes the maximum time
(quadratic) to sort the elements i.e. the worst case.
Ashwini S Data Structures with C++ 07-11-2023
32
• When the input array is neither sorted nor in reverse order, then it takes average time.
These durations are denoted using asymptotic notations.
• The above expression can be described as a function f(n) belongs to the set O(g(n)) if there exists a positive constant
c such that it lies between 0 and cg(n), for sufficiently large n.
• For any value of n, the running time of an algorithm does not cross the time provided by O(g(n)).
• Since it gives the worst-case running time of an algorithm, it is widely used to analyze an algorithm as we are always
interested in the worst-case scenario.
Ashwini S Data Structures with C++ 07-11-2023
34
Ashwini S Data Structures with C++ 07-11-2023
35 O(N)
• O(n) represents a linear time complexity. It means that the number of basic operations performed by
the algorithm is directly proportional to the size of the input 'n’.
Examples: 1. Linear Search: Consider a simple linear search algorithm that looks for a specific element in an
unsorted array. In the worst case, you may need to examine every element in the array to find the desired element.
If the array has 'n' elements, the worst-case time complexity of this algorithm is O(n). This means that as the size of
the array increases, the number of comparisons made by the algorithm also increases linearly.
• 2. Summing Elements: If you have an array of 'n' elements and you want to sum all the elements, you
will need to iterate through each element once. The time complexity of this operation is O(n) because
you perform 'n' additions (assuming addition is a basic operation).
Ashwini S Data Structures with C++ 07-11-2023
• An algorithm with O(1) time complexity takes the same amount of time to complete,
regardless of the size of the input.
• It is often considered the most efficient time complexity.
• Example: Accessing an element in an array by its index, performing basic arithmetic
operations, or looking up a value in a well-structured dictionary.
• An example is accessing an element in an array by its index. Whether the array has 10
elements or 1,000,000 elements, accessing a specific index takes the same amount of time
because it's a direct operation.
Ashwini S Data Structures with C++ 07-11-2023
• An algorithm with O(n^2) time complexity has a running time that is proportional to the
square of the input size.
• - It is commonly associated with nested loops or algorithms that compare all pairs of
elements.
• - Example: Selection sort, bubble sort, or algorithms that involve nested loops over an
array.
• A classic example is the Selection Sort algorithm. In this sorting algorithm, for each element
in the array, it compares it to all other elements in the array. As the size of the array
increases, the number of comparisons and swaps grows with the square of the input size,
resulting in O(n^2) complexity.
Ashwini S Data Structures with C++ 07-11-2023
• An algorithm with O(n^3) time complexity has a running time that is proportional to the
cube of the input size.
• - It is less efficient than quadratic time complexity and often occurs in algorithms with triple
nested loops.
• - Example: Some matrix multiplication algorithms, such as the naive matrix multiplication
method.
• An example is a matrix multiplication algorithm using the naive method. In this method, for
two n x n matrices, you have to perform n^2 multiplications and additions for each element of
the resulting matrix. This results in O(n^3) complexity.
Ashwini S Data Structures with C++ 07-11-2023
• An algorithm with O(2^n) time complexity has a running time that grows exponentially with
the input size.
• - It is typically associated with combinatorial problems or recursive algorithms that result in
an exponential number of function calls.
• - Example: Solving the traveling salesman problem with a brute-force approach, or some
recursive Fibonacci sequence calculations.
• An example is solving the Traveling Salesman Problem (TSP) using a brute-force approach. The
brute-force method examines all possible permutations of cities, which leads to 2^n possible
paths to consider. As a result, the running time becomes impractical for large inputs.
Ashwini S Data Structures with C++ 07-11-2023
• An algorithm with O(log n) time complexity has a running time that grows very slowly as the
input size increases.
• - It is highly efficient and is often associated with algorithms that divide the input in half at
each step.
• - Example: Binary search in a sorted array or various efficient data structures like balanced
search trees.
• A classic example is binary search. In binary search, you repeatedly divide the search space in
half, which results in logarithmic growth. For a sorted array with n elements, it takes at most
log (n) steps to find the target element.
Ashwini S Data Structures with C++ 07-11-2023
• The above expression can be described as a function f(n) belongs to the set Ω(g(n)) if there
exists a positive constant c such that it lies above cg(n), for sufficiently large n.
• For any value of n, the minimum time required by the algorithm is given by Omega Ω(g(n)).
Ashwini S Data Structures with C++ 07-11-2023
• Theta notation encloses the function from above and below. Since it
represents the upper and the lower bound of the running time of an
algorithm, it is used for analyzing the average-case complexity of an
algorithm.
• The above expression can be described as a function f(n) belongs to the set Θ(g(n)) if there exist positive constants c1 and
c2 such that it can be sandwiched between c1g(n) and c2g(n), for sufficiently large n.
• If a function f(n) lies anywhere in between c1g(n) and c2g(n) for all n ≥ n0, then f(n) is said to be asymptotically tight bound.
Ashwini S Data Structures with C++ 07-11-2023
43 SPACE COMPLEXITY
• The space complexity can be defined as amount of memory required by an algorithm to run.
• The space Complexity of an algorithm is the total space taken by the algorithm with respect to the
input size. Space complexity includes both Auxiliary space and space used by input.
• Let p be an algorithm, To compute the space complexity we use two factors: constant and
instance characteristics. The space requirement S(p) can be given as
• S(p) = C + Sp
• where C is a constant i.e.. fixed part and it denotes the space of inputs and outputs.
• This space is an amount of space taken by instruction, variables and identifiers.
• Sp is a space dependent upon instance characteristics.
• This is a variable part whosespace requirement depend on particular problem instance.
Ashwini S Data Structures with C++ 07-11-2023
44
EX 1: Algorithm
add(a,b,c)
{
return a+b+c;
}
• If we assume a, b, c occupy one word size then total size comes to be 3 S(p) = C
EX 2: Algorithm
add(x,n)
{
} S(p) ≥ (n+3)
sum=0.0;
for i= 1 to n do sum:=sum+x[i];return sum;
• The n space required for x[], one space for n, one for i, and one for sum
Ashwini S Data Structures with C++ 07-11-2023
45 LINEAR SEARCH
• Linear Search is defined as a sequential search algorithm that starts at one end and goes through each
element of a list until the desired element is found, otherwise the search continues till the end of the data
set.
How Does Linear Search Algorithm Work?
In Linear Search Algorithm,
• If any element is found equal to the key, the search is successful and
the index of that element is returned.
• If no element is found equal to the key, the search yields “No match
found”.
Ashwini S Data Structures with C++ 07-11-2023
46 FOR EXAMPLE: CONSIDER THE ARRAY ARR[] = {10, 50, 30, 70, 80,
20, 90, 40} AND KEY = 30
• Step 1: Start from the first element (index 0) and compare key with each
element (arr[i]).
• Comparing key with first element arr[0]. SInce not equal, the iterator moves to
the next element as a potential match.
• Comparing key with next element arr[1]. SInce not equal, the iterator moves to
the next element as a potential match.
Ashwini S Data Structures with C++ 07-11-2023
47
• Step 2: Now when comparing arr[2] with key, the value matches. So the Linear
Search Algorithm will yield a successful message and return the index of the
element when key is found (here 2).
Ashwini S Data Structures with C++ 07-11-2023
48
49
Ashwini S Data Structures with C++ 07-11-2023
50
Ashwini S Data Structures with C++ 07-11-2023
51
Ashwini S Data Structures with C++ 07-11-2023
52
Ashwini S Data Structures with C++ 07-11-2023
53
Ashwini S Data Structures with C++ 07-11-2023
56 BUBBLE SORT
• Bubble sort is a sorting algorithm that compares two adjacent elements and swaps them
until they are in the intended order.
• Just like the movement of air bubbles in the water that rise up to the surface, each
element of the array move to the end in each iteration. Therefore, it is called a bubble
sort.
Ashwini S Data Structures with C++ 07-11-2023
58 2. REMAINING ITERATION
59
• The array is sorted when all the unsorted elements are placed at their correct positions.
Ashwini S Data Structures with C++ 07-11-2023
61
Ashwini S Data Structures with C++ 07-11-2023
62
Ashwini S Data Structures with C++ 07-11-2023
64
• nearly equals to n2
• Hence, Complexity: O(n2)
Also, if we observe the code, bubble sort requires two loops. Hence, the complexity is n*n = n2
Ashwini S Data Structures with C++ 07-11-2023
65 TIME COMPLEXITIES