Unit-1
Unit-1
The data structure is a specific way of storing and organizing data in the computer's memory so
that these data can be easily retrieved and efficiently used when needed later.
The data can be managed in many different ways, such as a logical or mathematical model for a
particular organization of data is called a data structure.
For example, we have some data which has, player's name "Virat" and age 26. Here "Virat" is
of String data type and 26 is of integer data type.
Data Structures are the main part of many computer science algorithms as they enable the
programmers to handle the data in an efficient way. It plays a vitle role in enhancing the
performance of a software or a program as the main function of the software is to store and
retrieve the user’s data as fast as possible
● Queues: A queue is an important data structure in programming. A queue follows the FIFO
(First In First Out) method and is open at both of its ends. Data insertion is done at one end
rear end or the tail of the queue while deletion is done at the other end called the front end
or the head of the queue.
● Stacks: Stack is a linear list in which insertion and deletions are allowed only at one end,
called top.
● Linked lists: Linked list is a linear data structure which is used to maintain a list in the
memory. Each node of the list contains a pointer to its adjacent node.
Anything that can store data can be called as a data structure, hence Integer, Float, Boolean, Char
etc, all are data structures. They are known as Primitive Data Structures.
Then we also have some complex Data Structures, which are used to store large and connected
data. Some example of Abstract Data Structure are :
Linked List
Tree
Graph
Stack,Queue etc.
Operations on data structure
1) Traversing: Every data structure contains the set of data elements. Traversing the data structure
means visiting each element of the data structure in order to perform some specific operation like
searching or sorting.
Example: If we need to calculate the average of the marks obtained by a student in 6 different
subject, we need to traverse the complete array of marks and calculate the total sum, then we will
devide that sum by the number of subjects i.e. 6, in order to find the average.
2) Insertion: Insertion can be defined as the process of adding the elements to the data structure at
any location.
If the size of data structure is n then we can only insert n-1 data elements into it.
3) Deletion:The process of removing an element from the data structure is called Deletion. We can
delete an element from the data structure at any random location.
If we try to delete an element from an empty data structure then underflow occurs.
4) Searching: The process of finding the location of an element within the data structure is called
Searching. There are two algorithms to perform searching, Linear Search and Binary Search. We
will discuss each one of them later in this tutorial.
5) Sorting: The process of arranging the data structure in a specific order is known as Sorting.
There are many algorithms that can be used to perform sorting, for example, insertion sort,
selection sort, bubble sort, etc.
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
● An abstract data type (or ADT) is a programmer-defined data type that specifies a
set of data values and a collection of well-defined operations that can be performed
on those values.
●The definition of ADT only mentions what operations are to be performed but not
how these operations will be implemented.
●The process of providing only the essentials and hiding the details is known as
abstraction.
The implementations of the various operations are hidden inside the black box, the
contents of which we do not have to know in order to utilize the ADT. There are several
advantages of working with abstract data types and focusing on the \what" instead of
the\how."
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.
Now we’ll define three ADTs namely List ADT, Stack ADT, Queue ADT.
List ADT
● The data is generally stored in key sequence in a list which has a head structure
consisting of count, pointers and address of compare function needed to compare the data
in the list.
●
Stack ADT
Stack is a linear data structure in which data can be only accessed from its top. It only has two
operations i.e. push (used to insert data to the stack top) and pop (used to remove data from the
stack top).
Queue ADT
Queue is a linear data structure in which data can be accessed from both of its ends i.e. front and
rear. It only has two operations i.e. push (used to insert data to the rear of the queue) and pop
(used to remove data from the front of the queue).
● enqueue() – Insert an element at the end of the queue.
● dequeue() – Remove and return the first element of the queue, if the queue is not empty.
● peek() – Return the element of the queue without removing it, if the queue is not empty.
● size() – Return the number of elements in the queue.
● isEmpty() – Return true if the queue is empty, otherwise return false.
● isFull() – Return true if the queue is full, otherwise return false.
Built-in Data Structures
As the name suggests, these Data Structures are built-in with Python which makes
programming easier and helps programmers use them to obtain solutions faster. Let’s
discuss each of them in detail.
Lists
Lists are used to store data of different data types in a sequential manner. There are
addresses assigned to every element of the list, which is called as Index. The index
value starts from 0 and goes on until the last element called the positive index. There is
also negative indexing which starts from -1 enabling you to access elements from the
last to first. Let us now understand lists better with the help of an example program.
Creating a list
To create a list, you use the square brackets and add elements into it accordingly. If you
do not pass any elements inside the square brackets, you get an empty list as the output.
Output:
[]
[1, 2, 3, ‘example’, 3.132]
Adding Elements
Adding the elements in the list can be achieved using the append(), extend() and insert()
functions.
● The append() function adds all the elements passed to it as a single element.
● The extend() function adds the elements one-by-one into the list.
● The insert() function adds the element passed to the index value and increase
the size of the list too.
Output:
[1, 2, 3]
[1, 2, 3, [555, 12]]
[1, 2, 3, [555, 12], 234, ‘more_example’]
[1, ‘insert_example’, 2, 3, [555, 12], 234, ‘more_example’]
Deleting Elements
● To delete elements, use the del keyword which is built-in into Python but this
does not return anything back to us.
● If you want the element back, you use the pop() function which takes the index
value.
● To remove an element by its value, you use the remove() function.
Output:
[1, 2, 3, ‘example’, 3.132, 30]
[1, 2, 3, 3.132, 30]
Popped Element: 2 List remaining: [1, 3, 3.132, 30]
[]
Accessing Elements
Accessing elements is the same as accessing Strings in Python. You pass the index
values and hence can obtain the values as needed.
Output:
1
2
3
example
3.132
10
30
[1, 2, 3, ‘example’, 3.132, 10, 30]
example
[1, 2]
[30, 10, 3.132, ‘example’, 3, 2, 1]
Other Functions
You have several other functions that can be used when working with lists.
● The len() function returns to us the length of the list.
● The index() function finds the index value of value passed where it has been
encountered the first time.
● The count() function finds the count of the value passed to it.
● The sorted() and sort() functions do the same thing, that is to sort the values of
the list. The sorted() has a return type whereas the sort() modifies the original list.
Output:
6
3
2
[1, 2, 3, 10, 10, 30]
[30, 10, 10, 3, 2, 1]
Dictionary
Dictionaries are used to store key-value pairs. To understand better, think of a phone
directory where hundreds and thousands of names and their corresponding numbers
have been added. Now the constant values here are Name and the Phone Numbers
which are called as the keys. And the various names and phone numbers are the values
that have been fed to the keys. If you access the values of the keys, you will obtain all
the names and phone numbers. So that is what a key-value pair is. And in Python, this
structure is stored using Dictionaries. Let us understand this better with an example
program.
Creating a Dictionary
Dictionaries can be created using the flower braces or using the dict() function. You
need to add the key-value pairs whenever you work with dictionaries.
Output:
{}
{1: ‘Python’, 2: ‘Java’}
Tuple
Tuples are the same as lists are with the exception that the data once entered into the
tuple cannot be changed no matter what. The only exception is when the data inside the
tuple is mutable, only then the tuple data can be changed. The example program will
help you understand better.
ARRAY
● The most basic structure for storing and accessing a collection of data is
the array.
Representation of Array
The representation of an array can be defined by its declaration. A declaration means
allocating memory for an array of a given size.
# Python code
arr3 = [28.5, 36.5, 40.2] # This array will store floating elements
Types of arrays:
There are majorly two types of arrays:
● One-Dimensional array: A One-Dimensional Array is the simplest form of an
Array in which the elements are stored linearly and can be accessed individually
by specifying the index value of each element stored in the array.
● Initialization Syntax
● To Initialize the 1D Array, we simply add a list to the right side of the declaration
syntax of the 1D Array. In simple terms, we assign values to the declared 1D Array
as per the array size specified.
● Example
1D array
int
2D array
Two popular search methods are Linear Search and Binary Search.
In Linear search, we simply traverse the list completely and match each element of the
list with the item whose location is to be found.
If the match is found, then the location of the item is returned; otherwise, the algorithm
returns NULL.
It is widely used to search an element from the unordered list, i.e., the list in which items
are not sorted.
1. Time Complexity
Case Time Complexity
o Best Case Complexity - In Linear search, best case occurs when the element we
are finding is at the first position of the array. The best-case time complexity of
linear search is O(1).
o Average Case Complexity - The average case time complexity of linear search
is O(n).
o Worst Case Complexity - In Linear search, the worst case occurs when the
element we are looking is present at the end of the array. The worst-case in linear
search could be when the target element is not present in the given array, and we
have to traverse the entire array. The worst-case time complexity of linear search
is O(n).
The time complexity of linear search is O(n) because every element in the array is
compared only once.
Algorithm
1. Binary_Search(a, lower_bound, upper_bound, val) // 'a' is the given array, 'lower_bound' is the index of
the first array element, 'upper_bound' is the index of the last array element, 'val' is the value to search
2. Step 1: set beg = lower_bound, end = upper_bound, pos = - 1
3. Step 2: repeat steps 3 and 4 while beg <=end
4. Step 3: set mid = (beg + end)/2
5. Step 4: if a[mid] = val
6. set pos = mid
7. print pos
8. go to step 6
9. else if a[mid] > val
10. set end = mid - 1
11. else
12. set beg = mid + 1
13. [end of if]
14. [end of loop]
15. Step 5: if pos = -1
16. print "value is not present in the array"
17. [end of if]
18. Step 6: exit
Binary Search Algorithm: The basic steps to perform Binary Search are:
●Sort the array in ascending order.
●Set the low index to the first element of the array and the high index to the last element.
●Set the middle index to the average of the low and high indices.
●If the element at the middle index is the target element, return the middle index.
●If the target element is less than the element at the middle index, set the high index to the middle
index – 1.
●If the target element is greater than the element at the middle index, set the low index to the
middle index + 1.
●Repeat steps 3-6 until the element is found or it is clear that the element is not present in the
array.
Bubble Sort
Bubble Sort is a simple algorithm which is used to sort a given set of n elements
provided in form of an array with n number of elements. Bubble Sort compares all the
element one by one and sort them based on their values.
If the given array has to be sorted in ascending order, then bubble sort will start by
comparing the first element of the array with the second element, if the first element is
greater than the second element, it will swap both the elements, and then move on to
compare the second and the third element, and so on.
If we have total n elements, then we need to repeat this process for n-1 times.
It is known as bubble sort, because with every complete iteration the largest element in
the given array, bubbles up towards the last place or the highest index, just like a water
bubble rises up to the water surface.
Sorting takes place by stepping through all the elements one-by-one and comparing it
with the adjacent element and swapping them if required.
Following are the steps involved in bubble sort(for sorting a given array in ascending
order):
1. Starting with the first element(index = 0), compare the current element with the
next element of the array.
2. If the current element is greater than the next element of the array, swap them.
3. If the current element is less than the next element, move to the next
element. Repeat Step 1.
Algorithm
In the algorithm given below, suppose arr is an array of n elements. The
assumed swap function in the algorithm will swap the values of given array elements.
1. begin BubbleSort(arr)
2. for all array elements
3. if arr[i] > arr[i+1]
4. swap(arr[i], arr[i+1])
5. end if
6. end for
7. return arr
8. end BubbleSort
First Pass
Sorting will start from the initial two elements. Let compare them to check which is
greater.
Here, 32 is greater than 13 (32 > 13), so it is already sorted. Now, compare 32 with 26.
Here, 26 is smaller than 36. So, swapping is required. After swapping new array will look
like -
Here, 35 is greater than 32. So, there is no swapping required as they are already sorted.
Now, the comparison will be in between 35 and 10.
Here, 10 is smaller than 35 that are not sorted. So, swapping is required. Now, we reach
at the end of the array. After first pass, the array will be -
Second Pass
The same process will be followed for second iteration.
Here, 10 is smaller than 32. So, swapping is required. After swapping, the array will be -
Here, 10 is smaller than 26. So, swapping is required. After swapping, the array will be -
Fourth pass
Similarly, after the fourth iteration, the array will be -
Hence, there is no swapping required, so the array is completely sorted.
Bubble sort complexity
Now, let's see the time complexity of bubble sort in the best case, average case, and
worst case. We will also see the space complexity of bubble sort.
1. Time Complexity
Case Time Complexity
o Best Case Complexity - It occurs when there is no sorting required, i.e. the array
is already sorted. The best-case time complexity of bubble sort is O(n).
o Average Case Complexity - It occurs when the array elements are in jumbled
order that is not properly ascending and not properly descending. The average
2
case time complexity of bubble sort is O(n ).
o Worst Case Complexity - It occurs when the array elements are required to be
sorted in reverse order. That means suppose you have to sort the array elements
in ascending order, but its elements are in descending order. The worst-case time
2
complexity of bubble sort is O(n ).
Advantages:
●Bubble sort is easy to understand and implement.
●It does not require any additional memory space.
●It’s adaptability to different types of data.
Disadvantages
●Bubble sort has a time complexity of O(n^2) which makes it very slow for large data sets.
●It is not efficient for large data sets, because it requires multiple passes through the data.
●It is not a stable sorting algorithm, meaning that elements with the same key value may not
maintain their relative order in the sorted output.
Selection Sort
In selection sort, the smallest value among the unsorted elements of the array is selected in every pass and
inserted to its appropriate position into the array. It is also the simplest algorithm. It is an in-place comparison
sorting algorithm. In this algorithm, the array is divided into two parts, first is sorted part, and another one is the
unsorted part. Initially, the sorted part of the array is empty, and unsorted part is the given array. Sorted part is
placed at the left, while the unsorted part is placed at the right.
In selection sort, the first smallest element is selected from the unsorted array and placed at the first position.
After that second smallest element is selected and placed in the second position. The process continues until
the array is entirely sorted.
Selection sort is generally used when -
o A small array is to be sorted
o Swapping cost doesn't matter
o It is compulsory to check all elements
Now, for the first position in the sorted array, the entire array is to be scanned sequentially.
At present, 12 is stored at the first position, after searching the entire array, it is found that 8 is the
smallest value.
So, swap 12 with 8. After the first iteration, 8 will appear at the first position in the sorted array.
For the second position, where 29 is stored presently, we again sequentially scan the rest of the items
of unsorted array. After scanning, we find that 12 is the second lowest element in the array that should
be appeared at second position.
Now, swap 29 with 12. After the second iteration, 12 will appear at the second position in the sorted
array. So, after two iterations, the two smallest values are placed at the beginning in a sorted way.
The same process is applied to the rest of the array elements. Now, we are showing a pictorial
representation of the entire sorting process.