0% found this document useful (0 votes)
30 views33 pages

Array Ds 1 Chapter

Uploaded by

anil shinde
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views33 pages

Array Ds 1 Chapter

Uploaded by

anil shinde
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 33

1

Unit 1. Array as a Data Structure [4 Hours]


1.1 Data structure, types- linear and nonlinear data structure

Data Structure is a branch of Computer Science. The study of data


structure allows us to understand the organization of data and the
management of the data flow in order to increase the efficiency of any
process or program. Data Structure is a particular way of storing and
organizing data in the memory of the computer so that these data can
easily be retrieved and efficiently utilized in the future when required. The
data can be managed in various ways, like the logical or mathematical
model for a specific organization of data is known as a data structure.

● Linear data structure: Data structure in which data elements are arranged
sequentially or linearly, where each element is attached to its previous and
next adjacent elements, is called a linear data structure.
Examples of linear data structures are array, stack, queue, linked list, etc.
● Static data structure: Static data structure has a fixed memory size. It is
easier to access the elements in a static data structure.
An example of this data structure is an array.
● Dynamic data structure: In dynamic data structure, the size is not fixed. It
can be randomly updated during the runtime which may be considered
efficient concerning the memory (space) complexity of the code.
Examples of this data structure are queue, stack, etc.
2

● Non-linear data structure: Data structures where data elements are not
placed sequentially or linearly are called non-linear data structures. In a non-
linear data structure, we can’t traverse all the elements in a single run only.
Examples of non-linear data structures are trees and graphs.
● For example, we can store a list of items having the same data-type using
the array data structure.

1.2 Array introduction, need for array, representation, basic operation on array-create static
and dynamic array, traverse, insertion, deletion.

Arrays are defined as the collection of similar types of data items stored at
contiguous memory locations. It is one of the simplest data structures where
each data element can be randomly accessed by using its index number.

In C programming, they are the derived data types that can store the
primitive type of data such as int, char, double, float, etc. For example, if we
want to store the marks of a student in 6 subjects, then we don't need to
define a different variable for the marks in different subjects. Instead, we can
define an array that can store the marks in each subject at the contiguous
memory locations.

Properties of array
There are some of the properties of an array that are listed as follows -

o Each element in an array is of the same data type and carries the
same size that is 4 bytes.
o Elements in the array are stored at contiguous memory locations from
which the first element is stored at the smallest memory location.
o Elements of the array can be randomly accessed since we can
calculate the address of each element of the array with the given base
address and the size of the data element.

Representation of an array
We can represent an array in various ways in different programming
languages. As an illustration, let's see the declaration of array in C language
-

As per the above illustration, there are some of the following important
points -
3

o Index starts with 0.


o The array's length is 10, which means we can store 10 elements.
o Each element in the array can be accessed via its index.

Why are arrays required?


Arrays are useful because -

o Sorting and searching a value in an array is easier.


o Arrays are best to process multiple values quickly and easily.
o Arrays are good for storing multiple values in a single variable
- In computer programming, most cases require storing a large number
of data of a similar type. To store such an amount of data, we need to
define a large number of variables. It would be very difficult to
remember the names of all the variables while writing the programs.
Instead of naming all the variables with a different name, it is better to
define an array and store all the elements into it.

memory allocation of an array


As stated above, all the data elements of an array are stored at contiguous
locations in the main memory. The name of the array represents the base
address or the address of the first element in the main memory. Each
element of the array is represented by proper indexing.

We can define the indexing of an array in the below ways -

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 above image, we have shown the memory allocation of an array arr of
size 5. The array follows a 0-based indexing approach. The base address of
the array is 100 bytes. It is the address of arr[0]. Here, the size of the data
type used is 4 bytes; therefore, each element will take 4 bytes in the
memory.

How to access an element from the array?


4

We required the information given below to access any random element


from the array -

o Base Address of the array.


o Size of an element in bytes.
o Type of indexing, array follows.

The formula to calculate the address to access an array element -

1. Byte address of element A[i] = base address + size * ( i - first index)

Here, size represents the memory taken by the primitive data types. As an
instance, int takes 2 bytes, float takes 4 bytes of memory space in C
programming.

We can understand it with the help of an example -

Suppose an array, A[-10 ..... +2 ] having Base address (BA) = 999 and size of
an element = 2 bytes, find the location of A[-1].

L(A[-1]) = 999 + 2 x [(-1) - (-10)]

= 999 + 18

= 1017

Basic operations
Now, let's discuss the basic operations supported in the array -
o Traversal - This operation is used to print the elements of the array.
o Insertion - It is used to add an element at a particular index.
o Deletion - It is used to delete an element from a particular index.
o Search - It is used to search an element using the given index or by the
value.
o Update - It updates an element at a particular index.

Traversal operation
This operation is performed to traverse through the array elements. It prints
all array elements one after another. We can understand it with the below
program -

#include <iostream>
Using namespace std;
5

void main() {
int Arr[5] = {18, 30, 15, 70, 12};
int i;
cout<<"Elements of the array are:”<<”\n";
for(i = 0; i<5; i++)
{
cout<<Arr[i]<<”\n”;
}
}

Output

Elements of the array are


18
30
15
70
12

Insertion operation
This operation is performed to insert one or more elements into the array. As
per the requirements, an element can be added at the beginning, end, or at
any index of the array. Now, let's see the implementation of inserting an
element into the array.

#include <iostream>
using namespace std;
int main()
{
int arr[20] = { 18, 30, 15, 70, 12 };
int i, x, pos, n = 5;
printf("Array elements before insertion\n");
for (i = 0; i < n; i++)
cout<<arr[i]<<”\n”;
x = 50; // element to be inserted
pos = 4;
n++;
for (i = n-1; i >= pos; i--)
arr[i] = arr[i - 1];
arr[pos - 1] = x;
cout<<"Array elements after insertion<<”\n";
for (i = 0; i < n; i++)
6

cout<< arr[i]<<”\n”;
return 0;
}

Output

Array elements before insertion

18

30

15

70

12

Array elements after insertion

18

30

15

50

70

12

Deletion operation
As the name implies, this operation removes an element from the array and
then reorganizes all of the array elements.

#include <iostream>
using namespace std;
void main() {
int arr[] = {18, 30, 15, 70, 12};
7

int k = 30, n = 5;
int i, j;
cout<<"Given array elements are :<<”\n";
for(i = 0; i<n; i++)
{
cout<<arr[i]<<”\n”;
}

j = k;

while( j < n) {
arr[j-1] = arr[j];
j = j + 1;
}

n = n -1;

printf("\nElements of array after deletion:\n");

for(i = 0; i<n; i++) {


cout<<arr[i]<<”\n”;
}
}

Output

Given array elements are ;


18
30
15
70
12
Elements of array after deletion
18
30
15
70

1.3 Array applications–Searching method- Sequential search, Binary Search, Sorting, Method -
Insertion sort,

What is a linear search?


8

A linear search is also known as a sequential search that simply scans each
element at a time. Suppose we want to search an element in an array or list;
we simply calculate its length and do not jump at any item.

Let's consider a simple example.

Suppose we have an array of 10 elements as shown in the below


figure:

The above figure shows an array of character type having 10 values. If we


want to search 'E', then the searching begins from the 0 th element and scans
each element until the element, i.e., 'E' is not found. We cannot directly jump
from the 0th element to the 4th element, i.e., each element is scanned one by
one till the element is not found.
#include <iostream>
using namespace std;

int search(int arr[], int N, int x)


{
for (int i = 0; i < N; i++)
if (arr[i] == x)
return i;
return -1;
}

// Driver code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);

// Function call
int result = search(arr, N, x);
if(result == -1)
9

cout << "Element is not present in array"


else
cout << "Element is present at index " << result;
return 0;
}

What is a Binary search?


A binary search is a search in which the middle element is calculated to
check whether it is smaller or larger than the element which is to be
searched. The main advantage of using binary search is that it does not scan
each element in the list. Instead of scanning each element, it performs the
searching to the half of the list. So, the binary search takes less time to
search an element as compared to a linear search.
The one pre-requisite of binary search is that an array should be in
sorted order, whereas the linear search works on both sorted and unsorted
array. The binary search algorithm is based on the divide and conquer
technique, which means that it will divide the array recursively.

There are three cases used in the binary search:

Case 1: data<a[mid] then left = mid+1.

Case 2: data>a[mid] then right=mid-1

Case 3: data = a[mid] // element is found

In the above case, 'a' is the name of the array, mid is the index of the
element calculated recursively, data is the element that is to be
searched, left denotes the left element of the array and right denotes the
element that occur on the right side of the array.
Let's understand the working of binary search through an example.

Suppose we have an array of 10 size which is indexed from 0 to 9 as shown


in the below figure:

We want to search for 70 element from the above array.

Step 1: First, we calculate the middle element of an array. We consider two


variables, i.e., left and right. Initially, left =0 and right=9 as shown in the
below figure:
10

Step 2: As data>a[mid], so the value of left is incremented by mid+1, i.e.,


left=mid+1. The value of mid is 4, so the value of left becomes 5. Now, we
have got a subarray as shown in the below figure:
11

In the above figure, we can observe that a[mid]>data, so again, the value of
mid will be calculated in the next step.

Step 3: As a[mid]>data, the value of right is decremented by mid-1. The


value of mid is 7, so the value of right becomes 6. The array can be
represented as:
12

In the above figure, we can observe that a[mid]<data.

Step 4: As a[mid]<data, the left value is incremented by mid+1. The value


of mid is 5, so the value of left becomes 6.

Now the value of mid is calculated again by using the formula which we have
already discussed. The values of left and right are 6 and 6 respectively, so
the value of mid becomes 6 as shown in the below figure:

We can observe in the above figure that a[mid]=data. Therefore, the search
is completed, and the element is found successfully.
#include<iostream>
using namespace std;
int binarySearch(int arr[], int low, int high, int x)
{

if (high >= low)


{
13

int mid = low + (high - low) / 2;


if (arr[mid] == x)
return mid;
if (arr[mid] > x)
return binarySearch(arr, low, mid - 1, x);
else
return binarySearch(arr, mid + 1, high, x);
}
return -1;
}

int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };

// Element to be searched
int x = 10;
int n = sizeof(arr) / sizeof(arr[0]);
int result = binarySearch(arr, 0, n - 1, x);
if(result == -1)
cout << "Element is not present in array"
else
cout << "Element is present at index " << result;
return 0;
}

Insertion Sort
Algorithm
The simple steps of achieving the insertion sort are listed as follows -

Step 1 - If the element is the first element, assume that it is already sorted.
Return 1.

Step2 - Pick the next element, and store it separately in a key.

Step3 - Now, compare the key with all elements in the sorted array.

Step 4 - If the element in the sorted array is smaller than the current
element, then move to the next element. Else, shift greater elements in the
array towards the right.

Step 5 - Insert the value.

Step 6 - Repeat until the array is sorted.


14

Working of Insertion sort Algorithm


Now, let's see the working of the insertion sort Algorithm.

To understand the working of the insertion sort algorithm, let's take an


unsorted array. It will be easier to understand the insertion sort via an
example.

Let the elements of array are –


15
16

Program: Write a program to implement insertion sort in C++ language.

#include <iostream>
using namespace std;

void insert(int a[], int n) /* function to sort an aay with insertion sort */
{
int i, j, temp;

for (i = 1; i < n; i++) {


temp = a[i];
j = i - 1;

while(j>=0 && temp <= a[j]) /* Move the elements greater than temp
to one position ahead from their current position*/
17

{
a[j+1] = a[j];
j = j-1;
}
a[j+1] = temp;
}
}

void printArr(int a[], int n) /* function to print the array */


{
int i;
for (i = 0; i < n; i++)
cout << a[i] <<" ";
}

int main()
{
int a[] = { 89, 45, 35, 8, 12, 2 };
int n = sizeof(a) / sizeof(a[0]);
cout<<"Before sorting array elements are - "<<endl;
printArr(a, n);
insert(a, n);
cout<<"\nAfter sorting array elements are - "<<endl;
printArr(a, n);

return 0;
}
Output:

Before sorting array elements are - 89 45 35 8 12 2


After sorting array elements are – 2 8 12 35 45 89

1.4 Bubble sort, Merge Sort, Quick sort.


Bubble sort Algorithm
begin BubbleSort(arr)
for all array elements
if arr[i] > arr[i+1]
swap(arr[i], arr[i+1])
end if
end for
return arr
end BubbleSort
18

Let the elements of array are -


19
20
21

1. Time Complexity

Case Time Complexity

Best Case O(n)

Average Case O(n2)

Worst Case O(n2)


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 case time complexity of bubble sort is O(n2).
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 complexity of bubble sort
is O(n2).

2. Space Complexity

Space Complexity O(1)

Stable YES
o The space complexity of bubble sort is O(1). It is because, in bubble
sort, an extra variable is required for swapping.
o The space complexity of optimized bubble sort is O(2). It is because
two extra variables are required in optimized bubble sort.
22

Now, let's discuss the optimized bubble sort algorithm.

Write a program to implement bubble sort in C++ language.

#include<iostream>
using namespace std;
void print(int a[], int n) //function to print array elements
{
int i;
for(i = 0; i < n; i++)
{
cout<<a[i]<<" ";
}
}
void bubble(int a[], int n) // function to implement bubble sort
{
int i, j, temp;
for(i = 0; i < n; i++)
{
for(j = i+1; j < n; j++)
{
if(a[j] < a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}

}
int main()
{
int i, j,temp;
int a[5] = {45, 1, 32, 13, 26};
int n = sizeof(a)/sizeof(a[0]);
cout<<"Before sorting array elements are - \n";
print(a, n);
bubble(a, n);
cout<<"\nAfter sorting array elements are - \n";
print(a, n);
return 0;
}
Output
Before sorting array elements are - 45 1 32 13 26
23

After sorting array elements are – 1 13 26 32 45

Merge Sort

Algorithm
In the following algorithm, arr is the given array, beg is the starting
element, and end is the last element of the array.
MERGE_SORT(arr, beg, end)

if beg < end


set mid = (beg + end)/2
MERGE_SORT(arr, beg, mid)
MERGE_SORT(arr, mid + 1, end)
MERGE (arr, beg, mid, end)
end of if

END MERGE_SORT
24

Merge sort complexity


Now, let's see the time complexity of merge sort in best case, average case,
and in worst case. We will also see the space complexity of the merge sort.

1. Time Complexity

Case Time Complexity

Best Case O(n*logn)


25

Average Case O(n*logn)

Worst Case O(n*logn)

2. Space Complexity

Space Complexity O(n)

Stable YES
#include <iostream>

using namespace std;

/* Function to merge the subarrays of a[] */


void merge(int a[], int beg, int mid, int end)
{
int i, j, k;
int n1 = mid - beg + 1;
int n2 = end - mid;

int LeftArray[n1], RightArray[n2]; //temporary arrays

/* copy data to temp arrays */


for (int i = 0; i < n1; i++)
LeftArray[i] = a[beg + i];
for (int j = 0; j < n2; j++)
RightArray[j] = a[mid + 1 + j];

i = 0; /* initial index of first sub-array */


j = 0; /* initial index of second sub-array */
k = beg; /* initial index of merged sub-array */

while (i < n1 && j < n2)


{
if(LeftArray[i] <= RightArray[j])
{
a[k] = LeftArray[i];
i++;
}
else
{
a[k] = RightArray[j];
26

j++;
}
k++;
}
while (i<n1)
{
a[k] = LeftArray[i];
i++;
k++;
}

while (j<n2)
{
a[k] = RightArray[j];
j++;
k++;
}
}

void mergeSort(int a[], int beg, int end)


{
if (beg < end)
{
int mid = (beg + end) / 2;
mergeSort(a, beg, mid);
mergeSort(a, mid + 1, end);
merge(a, beg, mid, end);
}
}

/* Function to print the array */


void printArray(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
cout<<a[i]<<" ";
}

int main()
{
int a[] = { 11, 30, 24, 7, 31, 16, 39, 41 };
int n = sizeof(a) / sizeof(a[0]);
cout<<"Before sorting array elements are - \n";
printArray(a, n);
mergeSort(a, 0, n - 1);
27

cout<<"\nAfter sorting array elements are - \n";


printArray(a, n);
return 0;
}
Output:
Before sorting array elements are –
11 30 24 7 31 16 39 41
After sorting array elements are –
7 11 16 24 30 31 39 41

Quick Sort
Algorithm:

QUICKSORT (array A, start, end) {


1 if (start < end)
2{
3 p = partition(A, start, end)
4 QUICKSORT (A, start, p - 1)
5 QUICKSORT (A, p + 1, end)
6}
}

The partition algorithm rearranges the sub-arrays in a place.

PARTITION (array A, start, end)


{
1 pivot ? A[end]
2 i ? start-1
3 for j ? start to end -1 {
4 do if (A[j] < pivot) {
5 then i ? i + 1
6 swap A[i] with A[j]
7 }}
8 swap A[i+1] with A[end]
9 return i+1
}
28
29
30

1. Time Complexity
31

Case Time Complexity

Best Case O(n*logn)

Average Case O(n*logn)

Worst Case O(n2)

2. Space Complexity

Space Complexity O(n*logn)

Stable NO
#include <iostream>

using namespace std;

/* function that consider last element as pivot,


place the pivot at its exact position, and place
smaller elements to left of pivot and greater
elements to right of pivot. */
int partition (int a[], int start, int end)
{
int pivot = a[end]; // pivot element
int i = (start - 1);

for (int j = start; j <= end - 1; j++)


{
// If current element is smaller than the pivot
if (a[j] < pivot)
{
i++; // increment index of smaller element
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
int t = a[i+1];
a[i+1] = a[end];
a[end] = t;
return (i + 1);
}
32

/* function to implement quick sort */


void quick(int a[], int start, int end) /* a[] = array to be sorted, start = Start
ing index, ed = Ending index */
{
if (start < end)
{
int p = partition(a, start, end); //p is the partitioning index
quick(a, start, p - 1);
quick(a, p + 1, end);
}
}

/* function to print an array */


void printArr(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
cout<<a[i]<< " ";
}
int main()
{
int a[] = { 23, 8, 28, 13, 18, 26 };
int n = sizeof(a) / sizeof(a[0]);
cout<<"Before sorting array elements are - \n";
printArr(a, n);
quick(a, 0, n - 1);
cout<<"\nAfter sorting array elements are - \n";
printArr(a, n);

return 0;
}

Output:
Before sorting array elements are –
23 8 28 13 18 26

After sorting array elements are –


8 13 18 23 26 28

You might also like