Back to Study material
PPS

UNIT- 4

Arrays & Basic Algorithms


An array is a collection of data items, all of the same type, accessed using a common name.

A one-dimensional array is like a list;  A two dimensional array is like a table;  The C language places no limits on the number of dimensions in an array, though specific implementations may.

Some texts refer to one-dimensional arrays as vectors, two-dimensional arrays as matrices, and use the general term arrays when the number of dimensions is unspecified or unimportant.

Declaring Arrays

Array variables are declared identically to variables of their data type, except that the variable name is followed by one pair of square [ ] brackets for each dimension of the array.

Uninitialized arrays must have the dimensions of their rows, columns, etc. listed within the square brackets.

Dimensions used when declaring arrays in C must be positive integral constants or constant expressions.

In C99, dimensions must still be positive integers, but variables can be used, so long as the variable has a positive value at the time the array is declared. ( Space is allocated only once, at the time the array is declared. The array does NOT change sizes later if the variable used to declare it changes. )

 

Examples:

        int i, j, intArray[ 10 ], number;

        float floatArray[ 1000 ];

        int tableArray[ 3 ][ 5 ];      /* 3 rows by 5 columns */

 

        const int NROWS = 100;      // ( Old code would use #define NROWS 100 )

        const int NCOLS = 200;      // ( Old code would use #define NCOLS 200 )

        float matrix[ NROWS ][ NCOLS ];

 

4.1.1 Array notation and representation

Array is defined as a collection of elements of same data type. Hence it is also called as homogeneous variable. Total number of elements in array defines size of array. Position of element in an array defines index or subscript of particular element. Array index always starts with zero. If the size of array is n then index ranges from 0 to n–1. There can be array of integer, floating point or character values. Character array is called as String.

Eg.1  A=      

                                          0                   1                 2               3              4

  • This example illustrates integer array A of size 5.
  • Array index ranges from 0 to 4.
  • Elements of array are {10, 20, 40, 5, 25}.

 

4.1.2 Manipulating array elements

An element is accessed by indexing the array name. This is done by placing the index of the element within square brackets after the name of the array.

For example

double salary = balance[9];

The above statement will take the 10th element from the array and assign the value to salary variable.

The following example Shows how to use all the three above mentioned concepts viz. declaration, assignment, and accessing arrays

#include <stdio.h>

 

int main () {

 

   int n[ 10 ]; /* n is an array of 10 integers */

   int i,j;

 

   /* initialize elements of array n to 0 */        

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

      n[ i ] = i + 100; /* set element at location i to i + 100 */

   }

 

   /* output each array element's value */

   for (j = 0; j < 10; j++ ) {

      printf("Element[%d] = %d\n", j, n[j] );

   }

 

   return 0;

}

When the above code is compiled and executed, it produces the following result

Element[0] = 100

Element[1] = 101

Element[2] = 102

Element[3] = 103

Element[4] = 104

Element[5] = 105

Element[6] = 106

Element[7] = 107

Element[8] = 108

Element[9] = 109

 

4.1.3 Using multi-dimensional arrays

1-D array has 1 row and multiple columns but multidimensional array has of multiple rows and multiple columns.

 

Two Dimensional array:

It is the simplest multidimensional array. They are also called as matrix.

 

Declaration:

data-type array_name[no.of rows][no. of columns];

 

Total no of elements= No.of rows * No. of Columns

 

Example 3: int a[2][3]

This example illustrates two dimensional array a of 2 rows and 3 columns.

 

 

   Col 0  Col 1  Col 2

  

Row 0

a[0][0]

 

a[0][1]

 

a[0][2]

 

a[1][0]

 

a[1][1]

 

a[1][2]

 

 

Row 1

  Fig.2: Index positions of elements of a[2][3]

 

Total no of elements: 2*3=6

Total no of bytes occupied: 6( total no.of elements )*2(Size of one element)=12

Initialization and Storage Representation:

In C, two dimensional arrays can be initialized in different number of ways. Specification of no. of columns in 2 dimensional array is mandatory while no of rows is optional.

int a[2][3]={{1,3,0},   // Elements of 1st row

      {-1,5,9}}; //  Elements of 2nd  row

 

                 OR

 

int a[][3]={{1,3,0},    // Elements of 1st row

      {-1,5,9}}; //  Elements of 2nd  row

 

 

                             OR

 

int a[2][3]={1,3,0,-1,5,9};

 

Fig. 3 gives general storage representation of 2 dimensional array     

 

      Col 0    Col 1                  Col n

 

 

 Row 0             

 

a[0][0]

 

a[0][1]

 

 

  ---

a[0][n]

 

a[1][0]

 

a[1][1]

 

 

  ---

a[1][n]

 

-

-

 

-

-

 

a[m][0]

 

a[m][1]

 

 

a[m][n]

 

        Row 1

 

 -

        -

    Row m

  Fig.3 General Storage Representation of 2 dimensional array.

 

 

Eg 4.  int a[2][3]={1,3,0,-1,5,9}

1

 

3

0

-1

 

5

9

                   

           Row 0

                                Row 1

                Col 0      col1      col2

 

Accessing Two-Dimensional Array Elements:

An element in 2-dimensional array is accessed by using the subscripts i.e. row index and column index of the array. For example:

int val = A[1][2];

The above statement will access element from the 2nd row and third column of the array A i.e. element 9.

 

4.1.4 Character arrays and strings

If the size of array is n then index ranges from 0 to n-1. There can be array of integer, floating point or character values. Character array is called as String.

 

Eg.1  A=      

                0        1       2      3        4

  • This example illustrates integer array A of size 5.
  • Array index ranges from 0 to 4.
  • Elements of array are {10, 20, 40, 5, 25}.

Arrays can be categorized in following types

  1. One dimensional array
  2. Multi Dimensional array

These are described below.

The abstract model of string is implemented by defining a character array data type and we need to include header file ‘string.h’, to hold all the relevant operations of string. The string header file enables user to view complete string and perform various operation on the string. E.g. we can call ‘strlen’ function to find length of string, ‘strcat’ to concatenate two string, ‘strcpy’ to copy one string to another, ‘strrev’ to reverse the string. The definitions of all these functions are stored in the header file ‘string.h’.  So string functions with the user provided data becomes the new data type in ‘C’.

1

Fig. 4.1 : String data type

To use the functions related to strings, user only need to include ‘string.h’ header file. All the definitions details of these functions are keep hidden from the user, user can directly use these function without knowing all the implementation details. This is known as abstraction or hiding.

String Manipulation in C Language

Strings are also called as the array of character.

  • A special character usually known as null character (\0) is used to indicate the end of the string.
  • To read and write the string in C program %s access specifier is required.
  • C language provides several built in functions for the manipulation of the string
  • To use the built in functions for string, user need to include string.h header file.
  • Syntax for declaring string is

Char  string name[size of string];

 Char is the data type, user can give any name to the string by following all the rules of defining name of variable. Size of the string is the number of alphabet user  wants to store in string.

Example:

Sr. No.

Instructions

Description

  1.  

#include<stdio.h>

Header file included

2.      

#include<conio.h>

Header file included

3.      

void main()

Execution of program begins

4.      

{

String is declare with name str and size of storing 10  alphbates

5.      

 char str[10];

6.      

 clrscr();

Clear the output of previous screen

7.      

 printf("enter a string");

Print “enter a string”

8.      

 scanf("%s",&str);

Entered string is stored at address of str

9.      

 printf("\n user entered string is %s",str);

Print:  user entered string is (string entered by user)

10.  

 getch();

Used to hold the output screen

11.  

}

Indicates end of scope of main function

Following are the list of string manipulation function

Sr. No.

String Function

Purpose

  1.  

strcat

use to concatenate (append) one string to another

2.      

Strcmp

use to compare one string with another.

(Note: The comparison is case sensitive)

3.      

strchr

 

use to locate the first occurrence of a particular character in a given string

4.      

Strcpy

use to copy one string to another.

5.      

Strlen

use to find the length of a string in bytes,

 

4.1.5 Structure

A structure can be considered as a template used for defining a collection of variables under a single name. Structures help programmers to group elements of different data types into a single logical unit (Unlike arrays which permit a programmer to group only elements of same data type).

  • Why Use Structures

         Ordinary variables can hold one piece of information

         arrays can hold a number of pieces of information of the same data type.

For example, suppose you want to store data about a book. You might want to store its name (a string), its price (a float) and number of pages in it (an int).

If data about say 3 such books is to be stored, then we can follow two approaches:

      Construct individual arrays, one for storing names, another for storing prices and still another for storing number of pages.

      Use a structure variable.

Suppose we want to create a employee database. Then, we can define a structure

called employee with three elements id, name and salary. The syntax of this structure is as

follows:

struct employee  

{   int id;  

    char name[50];  

    float salary;  

};

Note:

  • Struct keyword is used to declare structure.
  • Members of structure are enclosed within opening and closing braces.
  • Usually structure type declaration appears at the top of the source code file, before any variables or functions are defined or maintained in separate header file.
  • Declaration of Structure reserves no space.
  • It is nothing but the Template / Map / Shape ” of the  structure .
  • Memory is created , very first time when the variable is created / Instance is created.
  • Structure variable declaration:

We can declare the variable of structure in two ways

  1. Declare the structure inside main function
  2. Declare the structure outside the main function.

1. Declare the structure inside main function

Following example show you, how structure variable is declared inside main function

struct employee  

{  

 int id;  

 char name[50];  

 float salary;  

};  

int main()

{

struct employee e1, e2; 

return 0;

}

In this example the variable of structure employee is created inside main function that e1 ,e2.

2. Declare the structure outside main function

Following example show you, how structure variable is declared outside the main function

 

struct employee  

{  

 int id;  

 char name[50];  

 float salary;  

}e1,e2;  

 

  • Memory allocation for structure

Memory is allocated to the structure only when we create the variable of structure.

Consider following example

 

 

  • Structure Initialization

1. When we declare a structure, memory is not allocated for un-initialized variable.

2. Let us discuss very familiar example of structure student , we can initialize structure variable

in different ways –

Way 1 : Declare and Initialize

struct student

{

char name[20];

int roll;

float marks;

}std1 = { "Poonam",89,78.3 };

In the above code snippet, we have seen that structure is declared and as soon as after declaration we

have initialized the structure variable.

std1 = { "Poonam",89,78.3 }

This is the code for initializing structure variable in C programming

Way 2 : Declaring and Initializing Multiple Variables

struct student

{

char name[20];

int roll;

float marks;

}

std1 = {"Poonam" ,67, 78.3};

std2 = {"Vishal",62, 71.3};

In this example, we have declared two structure variables in above code. After declaration of variable we have initialized two variable.

std1 = {"Poonam" ,67, 78.3};

std2 = {"Vishal",62, 71.3};

Way 3 : Initializing Single member

struct student

{

int mark1;

int mark2;

int mark3;

} sub1={67};

Though there are three members of structure,only one is initialized , Then remaining two members

are initialized with Zero. If there are variables of other data type then their initial values will be –

Data Type Default value if not initialized

integer 0

float 0.00

char NULL

Way 4 : Initializing inside main

struct student

{

int mark1;

int mark2;

int mark3;

};

void main()

{

struct student s1 = {89,54,65};

- - - - --

- - - - --

- - - - --

};

When we declare a structure then memory won’t be allocated for the structure. i.e only writing below

declaration statement will never allocate memory

struct student

{

int mark1;

int mark2;

int mark3;

};

We need to initialize structure variable to allocate some memory to the structure.

struct student s1 = {89,54,65};

 

4.1.6 Union

Unions are quite similar to the structures in C. Union is also a derived type as

structure. Union can be defined in same manner as structures just the keyword

used in defining union in union where keyword used in defining structure was struct.

union car

{

char name[50];

int price;

};

Union variables can be created in similar manner as structure variable.

union car

{

char name[50];

int price;

}c1, c2, *c3;

 

OR;

 

union car

{

char name[50];

int price;

};

-------Inside Function-----------

union car c1, c2, *c3;

In both cases, union variables c1, c2 and union pointer variable c3 of type union

car is created.

  • Memory allocation for union

Like structure memory is allocated to union only when we create the variable of it.

The memory is allocated to union according to the largest data members of the union.

  • Accessing members of an union
  • Array elements are accessed using the Subscript variable , Similarly Union members are accessed using dot [.] operator.
  • (.) is called as “union member Operator”.
  • Use this Operator in between “Union variable” & “member name”

union employee  

   {  

 int id;  

 char name[50];  

 float salary; 

} ;

void main()

   {

      union employee e1= { 1, “ABC”, 50000 };

    printf(“%d”, e. id);

     printf(“%s”, e. name);

   }

O/P-  garbage value, ABC

 

4.1.7 Enumerated data types

 

Enumeration is a user defined datatype in C language. It is used to assign names to the integral constants which makes a program easy to read and maintain. The keyword “enum” is used to declare an enumeration.

Here is the syntax of enum in C language,

enum enum_name{const1, const2, ....... };

The enum keyword is also used to define the variables of enum type. There are two ways to define the variables of enum type as follows.

enum week{sunday, monday, tuesday, wednesday, thursday, friday, saturday};

enum week day;

 

4.1.8 Array of structures

Structure is collection of different data type. An object of structure represents a singlerecord in memory, if we want more than one record of structure type, we have tocreate an array of structure or object. As we know, an array is a collection of similartype, therefore an array can be of structure type.

Syntax for declaring structure array

struct struct-name

{

datatype var1;

datatype var2;

- - - - - - - - - -

- - - - - - - - - -

datatype varN;

};

struct struct-name obj [ size ];

Example for declaring structure array

#include<stdio.h>

struct Employee

{

int Id;

char Name[25];

int Age;

long Salary;

};

void main()

{

int i;

struct Employee Emp[ 3 ]; //Statement 1

for(i=0;i<3;i++)

{

printf("\nEnter details of %d Employee",i+1);

printf("\n\tEnter Employee Id : ");

scanf("%d",&Emp[i].Id);

printf("\n\tEnter Employee Name : ");

scanf("%s",&Emp[i].Name);

printf("\n\tEnter Employee Age : ");

scanf("%d",&Emp[i].Age);

printf("\n\tEnter Employee Salary : ");

scanf("%ld",&Emp[i].Salary);

}

printf("\nDetails of Employees");

for(i=0;i<3;i++)

printf("\n%d\t%s\t%d\t%ld",Emp[i].Id,Emp[i].Name,Emp[i].Age,Emp[i].Salary);

}

Output :

Enter details of 1 Employee

Enter Employee Id : 101

Enter Employee Name : Suresh

Enter Employee Age : 29

Enter Employee Salary : 45000

Enter details of 2 Employee

Enter Employee Id : 102

Enter Employee Name : Mukesh

Enter Employee Age : 31

Enter Employee Salary : 51000

Enter details of 3 Employee

Enter Employee Id : 103

Enter Employee Name : Ramesh

Enter Employee Age : 28

Enter Employee Salary : 47000

Details of Employees

101 Suresh 29 45000

102 Mukesh 31 51000

103 Ramesh 28 47000

In the above example, we are getting and displaying the data of 3 employee using

array of object. Statement 1 is creating an array of Employee Emp to store the records

of 3 employees.

Array within Structure

As we know, structure is collection of different data type. Like normal data type, It can

also store an array as well.

Syntax for array within structure

struct struct-name

{

datatype var1; // normal variable

datatype array [size]; // array variable

- - - - - - - - - -

- - - - - - - - - -

datatype varN;

};

struct struct-name obj;

Example for array within structure

struct Student

{

int Roll;

char Name[25];

int Marks[3]; //Statement 1 : array of marks

int Total;

float Avg;

};

void main()

{

int i;

struct Student S;

printf("\n\nEnter Student Roll : ");

scanf("%d",&S.Roll);

printf("\n\nEnter Student Name : ");

scanf("%s",&S.Name);

S.Total = 0;

for(i=0;i<3;i++)

{

printf("\n\nEnter Marks %d : ",i+1);

scanf("%d",&S.Marks[i]);

S.Total = S.Total + S.Marks[i];

}

S.Avg = S.Total / 3;

printf("\nRoll : %d",S.Roll);

printf("\nName : %s",S.Name);

printf("\nTotal : %d",S.Total);

printf("\nAverage : %f",S.Avg);

}

Output :

Enter Student Roll : 10

Enter Student Name : Kumar

Enter Marks 1 : 78

Enter Marks 2 : 89

Enter Marks 3 : 56

Roll : 10

Name : Kumar

Total : 223

Average : 74.00000

In the above example, we have created an array Marks[ ] inside structure representing

3 marks of a single student. Marks[ ] is now a member of structure student and to

access Marks[ ] we have used dot operator(.) along with object S.

 

4.1.9 Passing arrays to functions

Passing array to function using call by value method

As we already know in this type of function call, the actual parameter is copied to the formal parameters.

#include <stdio.h>

void disp( char ch)

{

   printf("%c ", ch);

}

int main()

{

   char arr[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};

   for (int x=0; x<10; x++)

   {

       /* I’m passing each element one by one using subscript*/

       disp (arr[x]);

   }

 

   return 0;

}

Output:

a b c d e f g h i j

 

Passing array to function using call by reference

When we pass the address of an array while calling a function then this is called function call by reference. When we pass an address as an argument, the function declaration should have a pointer as a parameter to receive the passed address.

 

#include <stdio.h>

void disp( int *num)

{

    printf("%d ", *num);

}

 

int main()

{

     int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

     for (int i=0; i<10; i++)

     {

         /* Passing addresses of array elements*/

         disp (&arr[i]);

     }

 

     return 0;

}

Output:

 

1 2 3 4 5 6 7 8 9 0

 


The word algorithm means “a process or set of rules to be followed in calculations or other problem-solving operations”. Therefore, Algorithm refers to a set of rules/instructions that step-by-step define how a work is to be executed upon in order to get the expected results.

 

 

 

 It must have the following characteristics:

  • 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.
  • Well-Defined Inputs: If an algorithm says to take inputs, it should be well-defined inputs.
  • Well-Defined Outputs: The algorithm must clearly define what output will be yielded and it should be well-defined as well.
  • Finite-ness: The algorithm must be finite, i.e. it should not end up in an infinite loops or similar.
  • Feasible: The algorithm must be simple, generic and practical, such that it can be executed upon will 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 same, as expected.

 

 

4.2.1 Searching & Basic Sorting Algorithms (Bubble, Insertion and Selection)

Searching (Linear Search, Binary Search Etc.)

Sorting and Searching are fundamental operations in computer science. Sorting refers to the operation of arranging data in some given order. Searching refers to the operation of searching the particular record from the existing information.

Consider a database of banking system where information of all customers such as name, contact number, address, account number is stored. If a manager wants to search for a record of a particular customer, he has to look for that record from among all records that has been stored in a database. This process of looking up for a particular record in a database is referred as searching.

If records in a banking database are not ordered properly it will be very difficult for a manager to search for a specific record. On the contrary if all record are arranged in order according to some criteria like names in alphabetical order or account numbers in ascending order, searching becomes easy and fast. The process of ordering the records in a data base is called sorting. Thus for efficient searching sorting is necessary.

Linear Search

Given a collection of objects, the goal of search is to find a particular object in this collection. The objects have key values on which search is performed and data values which correspond to the information one wishes to retrieve once an object is found. For example, a telephone book is a collection of names on which one searches and telephone numbers which correspond to the data being sought. The collection of objects is often stored in a list or an array. Given a collection of objects in an array A[1.. n], the ith  element A[i] corresponds to the key value of the ith  object in the collection. The input to a search algorithm is an array of objects A, the number of objects n, and the key value being sought x.

 Thus Algorithm for Linear Search is

 1. start at one end of the list

 2. if the current element is not equal to the search target, move to the next element,

 3. stop when a match is found or the opposite end of the list is reached.

 Function for Linear search is

 find(values, target)

 {

  for( i = 0; i < values.length; i++)

   {

    if (values[i] == target)

   { return i; }

  }

  return –1;

 }

 If element is found this function returns index of that element otherwise it returns –1.

Example : we have an array of integers, like the following:

Elements

9

6

7

12

1

5

Index

0

1

2

3

4

5

 Let’s search for the number 7. According to function for linear search index for element 7 should be returned. We start at the beginning and check the first element in the array.

9

6

7

12

1

5

 First element is 9.Match is not found and hence we move to next element i.e 6.

9

6

7

12

1

5

 Again match is not found so move to next element i.e.7.

9

6

7

12

1

5

0

1

2

3

4

5

 We found the match at the index position 2. Hence output is 2.

 If we try to find element 10 in above array, it will return –1,as 10 is not present in the array.

Complexity Analysis of Linear Search:

 Let us assume element x is to be searched in array A of size n.

 An algorithm can be analyzed using following three cases.

 1. Worst case

 2. Average case

 3. Best case

 1. Worst case : In Linear search worst case happens when element to be searched is not present. When x is not present, the linear search function compares it with all the elements of A one by one. The size of A is n and hence x is to be compared with all n elements. Thus, the worst case time complexity of linear search would be O(n).

 2. Average case : In average case analysis, we take all possible inputs and calculate computing time for all of the inputs. Sum all the calculated values and divide the sum by total number of inputs. Following is the value of average case time complexity.

   Average Case Time = = 

    = O (n)

 3. Best Case : In linear search , the best case occurs when x is present at the first location. So time complexity in the best case would be O(1).

P1 : Program for Linear Search

 #include<stdio.h>
 #include<conio.h>

 int search(int [],int, int);
 void main()
 {
 int a[20],k,i,n,m;
 clrscr();
 printf(“\n\n ENTER THE SIZE OF ARRAY”);
 scanf(“%d”,&n);
 printf(“\n\nENTER THE ARRAY ELEMENTS\n\n”);
 for(i=0;i<n;i++)
 {
 scanf(“%d”,&a[i]);
 }
 printf(“\n\nENTER THE ELEMENT FOR SEARCH\n”);
 scanf(“%d”,&k);
 m=search(a,n,k);
 if(m==–1)
 {
 printf(“\n\nELEMENT IS NOT FOUND IN LIST”);
 }
 else
 {
 printf(“\n\nELEMENT IS FOUND AT LOCATION %d”,m);
 }
 }
 getch();
 }

 int search(int a[],int n,int k)
 {
 int i;
 for(i=0;i<n;i++)
 {
 if(a[i]==k)
 {
 return i;
 }
 }
 if(i==n)
 {
 return –1;
 }
 }

Merits :

 1. Simple and easy to implement

 2. It works well even on unsorted arrays.

 3. It is memory efficient as it does not require copying and partitioning of the array being searched.

Demerits :

  1. Suitable only for small number of values.
  2. It is slow as compared to binary search.

Binary Search

Binary Search requires sorted array.

Steps to perform binary search on sorted array A of size n are as follows.

1. Initialize lower and upper limit of array to be searched Low=0,High= n–1.

2. Find the middle position

  Mid=(Low + High)/2

3. Compare the input key value with the key value of the middle element of the array. It has 3 possibilities.

Case 1 : If keys match then return mid and print element found.

 if(key==A[mid])

 return mid

Case 2 : If key is less than middle element then element is present in left half of array. Update High and goto step 2. 

 if(key<A[mid])

 High= Mid–1

 goto step 2

Case 3 : If key is greater than middle element then element is present in right half of array. Update Low and goto step 2. 

 if(key>A[mid])

 Low= Mid+1

 goto step 2

Case 4: if(Low>High)

 Print element not found.

 Iterative algorithm for Binary Search

 int BinarySearch( int A[],int x)

 {

  int mid,n;

  int Low = 0;

  int High = n–1;

  while ( Low <= High )

  {

   mid = (Low + High) / 2;

   if ( A[mid] == x )

    return mid;

   if ( A[mid] > x )

    High = mid – 1;

   else Low = mid + 1;

  }

  return –1;

 }

Example 1 : Let array A= {–1, 5, 6, 18, 19, 25, 46, 78, 102, 114}. We want to find element ‘6’ using binary search.

–1

5

6

18

19

25

46

78

102

114

0

1

2

3

4

5

6

7

8

9

Solution:

Step 1 : Low=0, High= 9

Step 2 : Mid=(Low + High)/2

Mid = (0+9)/2 =4.5 i.e 4. It means middle element is located at position 4. So A[Mid] is 19.Thus

 Low=0

 Mid=4

 High=9   

Low

 

 

 

Mid

 

 

 

 

High

–1

5

6

18

19

25

46

78

102

114

0

1

2

3

4

5

6

7

8

9

Step 3 : Compare 6 with 19. It satisfies case 2 of step 3. so High= 4–1=3 and element is present in left half of array. We can ignore right half of array.

 Repeat step 2. So mid= (0+3)/2 = 1.5 i.e 1. mid is at position 1. Element 5 is present at position 1.

 Low = 0

 Mid = 1

 High = 3

Low

Mid

 

High

 

–1

5

6

18

19

0

1

2

3

4

Again compare 5 with 6. It satisfies case 3 of step 3. so

Low = 1+1=2.  

Repeat step 2. Mid= (2+ 3)/2= 2.5 i.e 2 .Mid is at position 2. Element 6 is at position 2.

Low=2

Mid=2

High=3  

 

 

Low, Mid

High

 

 

 

 

 

 

–1

5

6

18

19

0

1

2

3

4

 Compare 6 with 6.

Match is found. Return the position and print element found.

Example 2 : Find 103 in {–1, 5, 6, 18, 19, 25, 46, 78, 102, 114} using Binary Search.

Low

 

 

 

Mid

 

 

 

 

High

–1

5

6

18

19

25

46

78

102

114

0

1

2

3

4

5

6

7

8

9

Step 1 : Low=0

High=9

Step 2 : Mid=(0+9)/2=4

 So middle element is 19.

Step 3 : Compare(103,19)

 103>19 hence element is located at right half of array and we can ignore left half of array. Update Low and recalculate mid.

    Low = 4+1=5

    High = 9 

    Mid = (5+9)/2=7

Low

 

Mid

 

High

25

46

78

102

114

5

6

7

8

9

 Middle element is 78. Compare(103,78)

 103>78. Recalculate Low and Mid

    Low = 7+1=8

    High = 9

    Mid = (8+9)/2=8

Low, Mid

High

102

114

8

9

 Middle element is 102. Compare(103,102)

 103>102. Recalculate Low and Mid.

    Low = 8+1=9

    High = 9

 Here Low=High and match is not found hence we conclude that element is not present in array.

Example 3 : Find 44 in A={5,12,17,23,38,44,77,84,90} using binary search.

Step 1: Low=0

  High=8

  Mid=(0+8)/2=4

Low

 

 

 

Mid

 

 

 

High

5

12

17

23

38

44

77

84

90

0

1

2

3

4

5

6

7

8

 Middle element is 38. Compare(44,38)

 44>38.Thus element is located at right half of array and we can ignore left half of array. Recalculate Low and Mid.

    Low = (4+1)= 5

    High = 8

    Mid = (5+8)/2=6.5 i.e 6

Low

Mid

 

high

44

77

84

90

0

1

2

3

 Middle element is 77. Compare(44,77)

 44<77. Recalculate High and Mid.

 Low=5

    High = 6–1=5

    Mid = (5+5)/2=5

Low, Mid, high

 

 

 

44

77

84

90

0

1

2

3

 Middle element is 44. Compare(44,44)

 Match is Found. Return index and print “Element Found.”

 Algorithm for Recursive Binary Search

 int BinarySearch (int A[], int x, int Low, int High)
 {

  if (High > Low)

   return –1;

 int mid = (High + Low) / 2;

  if (A[mid] == x)

   return mid;

 if (A[mid] < x)

   return BinarySearch(A, x, mid+1, High);

 return BinarySearch(A, x, Low, mid–1);

 }

P2 : Program for Binary Search

 #include<stdio.h>
 #include<conio.h>
 void main()
 {
 int n,i,search,f=0,low,high,mid,a[20];
 clrscr();
 printf("Enter the number of elements:");
 scanf("%d",&n);
 for(i=1;i<=n;i++)
 { 
 printf("Enter the number in ascending order a[%d]=",i);
 scanf("%d",&a[i]);
 }
 printf("Enter the element to be searched:");
 scanf("%d",&search);
 low=0;
 high=n–1;
 while(low<=high)
 {
 mid=(low+high)/2;
 if(search<a[mid])
 {
 high=mid–1;
 }
 else if(search>a[mid])
 {
 low=mid+1;
 }
 else
 {
 f=1;
 printf("Element is found at the position %d:",mid);
 exit();
 }
 }
 if(f==0)
 {
 printf("Element not found");
 }
 getch();
 }

Complexity Analysis of Binary Search : 

 Assume our array size is 16.

 When n= 16 Binary Search is called to reduce size to n=8.

 When n= 8 Binary Search is called to reduce size to n=4.

 When n= 4 Binary Search is called to reduce size to n=2.

 When n= 2 Binary Search is called to reduce size to n=1 .

 Thus we see that Binary Search function is called 4 times

 i.e. 4 elements of the array were examined for n =16.

 Note that 16 = 24

 Let us consider a more general case where

 n is still a power of 2. Let us say n =2k

 After k searches, the while loop is executed k times and n reduces to size 1. Let us assume that each run of the while loop involves at most 4 operations.

 Thus total number of operations: 4k.

 The value of k can be determined from the expression

    2k = n

 Taking log of both sides

    k = log n

 Thus total number of operations = 4 log n.

 We conclude that the time complexity of the Binary search method is O(log n), which is much more efficient than the Linear Search method.

Merits :

 Binary Search is fast and efficient.

 Suitable for large number of values.

Demerits :

 Binary search works only on sorted array or list.

 

Basic Sorting Algorithms (Bubble, Insertion And Selection)

Bubble Sort     

Steps to perform Bubble sort are as follows.

Assume we want to sort the elements in ascending order and no two elements are equal.

1. Compare first element with second element. If first element is greater than next element, we interchange their position accordingly. i.e first element is moved to second element’s position and second element is moved to first element’s position. If No, then we don’t interchange any elements. 

2. The element in second position is compared with element in third position and the process of interchanging elements is performed if second is greater than third element. The whole process of comparing and interchanging is repeated till last element. When the process gets completed, the largest element in array will get placed in the last position of the array.

Let us consider array A of size n. Then Algorithm for Bubble sort is

1. Set i to 0.

2. Set j to 0.

3. if(A[j]>A[j+1])

    swap A[j],A[j+1]

4. Increment j

5. if j<(n–1–i) goto step 3

6. Increment i

7. if(i<n–1) goto step  2.

Example 1 : Suppose the following numbers are stored in an array A:

32

51

27

85

66

23

13

57

j = 0

1

2

3

4

5

6

7

 We apply bubble sort to array A. We discuss each pass separately.

Pass 1

 1. Compare j[0] and j[1]. Since 32 < 51, the list is not altered.

 2. Compare j[1] and j[2] Since 51 > 27, interchange 51 and 27 as follows:

32

51

27

85

66

23

13

57

j = 0

1

2

3

4

5

6

7

      

 Array A becomes

32

27

51

85

66

23

13

57

j = 0

1

2

3

4

5

6

7

 3. Compare j[2] and j[3]. Since 51 < 85, array is not altered.

 4. Compare j[3] and j[4]. Since 85 > 66, interchange 85 and 66 as follows:

32

27

51

85

66

23

13

57

j = 0

1

2

3

4

5

6

7

 

 Array A becomes

32

27

51

66

85

23

13

57

j = 0

1

2

3

4

5

6

7

 5. Compare j[4] and j[5]. Since 85 > 23, interchange 85 and 23 as follows:

32

27

51

66

85

23

13

57

j = 0

1

2

3

4

5

6

7

 

 Array A becomes

32

27

51

66

23

85

13

57

j = 0

1

2

3

4

5

6

7

 6. Compare j[5] and j[6]. Since 85 > 13, interchange 85 and 13 as follows:

32

27

51

66

23

85

13

57

j = 0

1

2

3

4

5

6

7

 

32

27

51

66

23

13

85

57

j = 0

1

2

3

4

5

6

7

 7. Compare j[6] and j[7]. Since 85 > 57, interchange 85 and 57 as follows:

32

27

51

66

23

13

85

57

j = 0

1

2

3

4

5

6

7

 

 Array A becomes

32

27

51

66

23

13

57

85

j = 0

1

2

3

4

5

6

7

 At the end of this first pass, the largest number, 85, has moved to the last position. However, the rest of the numbers are not sorted, even though some of them have changed their positions.

 Pass 2 will move second last number at second last position, Pass 3 will move third last number at third last position and so on. Here we show array after every pass.

Pass 2 :

27

33

51

23

13

57

66

85

j = 0

1

2

3

4

5

6

7

Pass 3 :

27

33

23

13

51

57

66

85

j = 0

1

2

3

4

5

6

7

Pass 4:

27

23

13

33

51

57

66

85

j = 0

1

2

3

4

5

6

7

Pass 5 :

23

13

27

33

51

57

66

85

j = 0

1

2

3

4

5

6

7

Pass 6 :

13

23

27

33

51

57

66

85

j = 0

1

2

3

4

5

6

7

 Hence the array is sorted in 6 passes.

 We will see one more example

Example 2 : Apply Bubble Sort on array A= {5,3,1,9,8,2,4,7}. 

j =0

5

3

1

9

8

2

4

7

j =1

3

5

1

9

8

2

4

7

j =2

3

1

5

9

8

2

4

7

j =3

3

1

5

9

8

2

4

7

j =4

3

1

5

8

9

2

4

7

j =5

3

1

5

8

2

9

4

7

j =6

3

1

5

8

2

4

9

7

j =7

3

1

5

8

2

4

7

9

 

 

Pass 2 : i=2 

3

1

5

8

2

4

7

9

1

3

5

8

2

4

7

9

1

3

5

8

2

4

7

9

1

3

5

8

2

4

7

9

1

3

5

2

8

4

7

9

1

3

5

2

4

8

7

9

1

3

5

2

4

7

8

9

Pass 3 :

1

3

5

2

4

7

8

9

1

3

5

2

4

7

8

9

1

3

5

2

4

7

8

9

1

3

2

5

4

7

8

9

1

3

2

4

5

7

8

9

Pass 4 :

1

3

2

4

5

7

8

9

1

3

2

4

5

7

8

9

1

2

3

4

5

7

8

9

 This array gets sorted in 4 passes only.

Example : Apply Bubble Sort on array A= {23,78,45,8,32,56}

Pass 1 :

23

78

45

8

32

56

23

78

45

8

32

56

23

45

78

8

32

56

23

45

8

78

32

56

23

45

8

32

78

56

23

45

8

32

56

78

 

 

Pass 2 :

23

45

8

32

56

78

23

45

8

32

56

78

23

8

45

32

56

78

23

8

32

45

56

78

Pass 3 :

23

8

32

45

56

78

8

23

32

45

56

78

 This array is sorted in 3 passes.

P3: Write a Program for Bubble sort in C

 #include <stdio.h>

 #include<conio.h>

  void bubble_sort(int A[], int n);

  int main()

 {

  int A[100], n, i, j, swap;

   printf("Enter number of elements\n");

  scanf("%d", &n);

   printf("Enter the elements\n", );

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

   scanf("%d", &A[i]);

   bubble_sort(A, n);

   printf("Sorted list in ascending order:\n");

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

        printf("%ld\n", A[i]);

   return 0;

 }

  void bubble_sort(int A[], int n)

 {

  int i, j, t;

  for (i = 0 ; i < ( n – 1 ); i++)

   { 

  for (j = 0 ; j < (n – i – 1); j++)

   {

   if (A[j] > list[j+1])

    {

   /* Swapping */

   t = A[j];

   A[j]   = A[j+1];

   A[j+1] = t;

        }

      }

    } 

 }

Complexity Bubble sort:

 Suppose we have a list with n elements, and each element perform n – 1 comparisons with elements to its left, and swap, if necessary.

 Best Case: If the list is already sorted, only one iteration is performed  and complexity is O(1).

 Average and Worst case: For n elements at most n – 1 swap operations is performed in each pass. The worst and average case complexity is O(n2).

Selection Sort

 Assume we want to sort list in ascending order. Selection sort finds the smallest element from unsorted list and swap it with the element in first position. Then it finds second smallest element and swap it with element at second position. This process is repeated till entire list is sorted in ascending order. Each time we swap elements,  we say that we  have completed a sort pass. A list of  n elements requires  n–1 passes to completely  rearrange the data.

 Procedure for every pass is as follows.

 Pass 1 : Find the position P of the smallest in the list of N elements A[l], A[2], . . . , A[N], and then interchange A[P] and A[1] . Then A[1] is sorted.

 Pass 2 : Find the position P of the smallest in the sublist of N –1 elements A[2], A[3],. . . , A[N], and then interchange A[P]and A[2]. Then A[l], A[2] is sorted.

 Pass 3 : Find the position P of the smallest in the sublist of N–2  elements A[3], A[4], . . . , A[N], and then interchange A[P] and A[3]. Then: A[l], A[2] , A[3] is sorted.

 Pass N –1 : Find the position P of the smaller of the elements A[N –1), A[N], and then interchange A[P] and A[N–1]. Then: A[l], A[2], . . . , A[N] is sorted. Thus A is sorted after N –1 passes.

Example 1 :

25

79

41

9

34

60

Fig. 4.2 : Original List

 We will apply selection sort on this list.

Pass 1 :

25

79

41

9

34

60

 

 

 Here smallest element is 9 and 25 is located at first position. so we swap 9 with 25.

After Pass 1

9

79

41

25

34

60

 

    Sorted      Unsorted sublist

 Now we find smallest element from unsorted sublist and place it in second position.

Pass 2 :

9

79

41

25

34

60

 

 

 Unsorted sublist has 25 as a smallest element and 79 is located at second position. Hence we swap 25 and 79.

 

 

After Pass 2 :

9

25

41

79

34

60

 

     Sorted                 Unsorted sublist

Pass 3 :

9

25

41

79

34

60

 

 

After Pass 3 :

9

25

34

79

41

60

 

   Sorted                 Unsorted sublist

Pass 4 :

9

25

34

79

41

60

 

 

After Pass 4 :

9

25

34

41

79

60

 


     Sorted  Unsorted sublist

Pass 5 :

9

25

34

41

79

60

 

After Pass 5 :

9

25

34

41

60

79

 Thus list is sorted.

 We will see one more example.

 Apply selection sort on array A= {77,30,40,10,88,20,65,56}

Pass 1 :

77

30

40

10

88

20

65

56

 

After Pass 1

10

30

40

77

88

20

65

56

Pass 2 :

10

30

40

77

88

20

65

56

 

After Pass 2

10

20

40

77

88

30

65

56

Pass 3 :

10

20

40

77

88

30

65

56

 

 

After Pass 3

10

20

30

77

88

40

65

56

Pass 4 :

 

10

20

30

77

88

40

65

56

 

After Pass 4

10

20

30

40

88

77

65

56

 

Pass 5 :

10

20

30

40

88

77

65

56

 

After Pass 5

10

20

30

40

56

77

65

56

 

Pass 6 :

10

20

30

40

56

77

65

88

 

After Pass 6

10

20

30

40

56

65

77

88

 Hence the list is sorted in ascending order by applying selection sort.

 Function for Selection Sort

 void selectionSort(int A[], int n)

 {

 int i, j, s, temp;

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

 {

 s = i;

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

 if(A[j] < A[s])

 s= j;

 // Smallest selected; swap with current element

 temp = A[i];

 A[i] = A[s];

 A[s] = temp;

 }

P4 : Program to perform Selection Sort.

 #include <stdio.h>

 int main()

 {

    int A[100], n, i, j, s, temp;

 /* n=total no. of elements in array

  s= smallest element in unsorted array

  temp is used for swapping */

   printf("Enter number of elements\n");

  scanf("%d", &n);

 

   printf("Enter %d integers\n", n);

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

   scanf("%d", &A[i]);

   for ( i = 0 ; i < ( n – 1 ) ; i++ )

  {

  s = i;

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

  {

   if ( A[s] > A[j] )

    s = j;

  }

  if ( s != i )

 {

  temp = A[i];

  A[i] = A[s];

  A[s] = temp;

  }

 }

  printf("Sorted list in ascending order:\n");

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

   printf("%d\n", A[i]);

  return 0;

 }

Output:

 Enter number of elements

 5

 Enter 5 integers

 4

 1

 7

 5

 9

 Sorted list in ascending order

 1

 4

 5

 7

 9

Complexity of Selection Sort :

 In selection sort outer for loop is executed n–1 times. On the kth time through the outer loop, initially the sorted list holds

 k–1 elements and unsorted portion holds n–k+1 elements.  In inner for loop 2 elements are compared each time.

 Thus, 2*(n–k) elements are examined by the inner loop during the k th pass through the outer loop. But k ranges from 1 to n–1.

 Total number of elements examined is:

    T(n) = 2*(n –1) + 2*(n–2) + 2*(n–3) + .. + 2*(n–(n–2))

     + 2*(n–(n–1))

    = 2*((n–1) + (n–2) + (n–3) + ... + 2 + 1)

 (or 2*(sum of first n–1 integers)

    = 2*((n–1)*n)/2)

    = n2 – n, so complexity of algorithm is O(n2).

Insertion Sort           

 Insertion Sort reads all elements from 1 to n and inserts each element at its proper position. This sorting method works well on small list of elements. 

 Procedure for each pass is as follows.

Pass 1 :

 A[l] by itself is trivially sorted.

Pass 2 :

 A[2] is inserted either before or after A[l] so that: A[l], A[2] is sorted.

Pass 3 :

 A[3] is inserted into its proper place so that: A[l], A[2], A[3] is sorted.

Pass 4 :

 A[4] is inserted into its proper place A[l], A[2], A[3], A[4] is sorted.

Pass N :

 A[N] is inserted into its proper place in  so that:

 A[l], A[ 2 ] , . . . , A[ N ] is sorted

Example : We will apply insertion sort on original list of Fig.3.Assume we are arranging elements in ascending order.

25

79

41

9

34

60

Fig. 4.3 : Original List

Pass 1 :

 First element is trivially sorted.

25

79

41

9

34

60

 

    Sorted                    unsorted sublist

Pass 2 : 

 We move to next element i.e 79. Element 79 is at its proper position as 25<79.So we do not alter the position of 79.

25

79

41

9

34

60

 

    Sorted            unsorted sublist

Pass 3: We move to next element i.e.41. As 25<41<79, 41 is inserted at 2nd position.

 

25

79

41

9

34

60

 

After Pass 3

25

41

79

9

34

60

 

    Sorted                            unsorted

Pass 4 :

 We move to next element i.e 9.Element 9 is smallest so it should be placed at first position.

25

41

79

9

34

60

 

 

9

25

41

79

34

60

 

     Sorted                       Unsorted sublist

Pass 5 :

 Consider next element 34. It should be placed between 25 and 41 i.e at position 3. 

9

25

41

79

34

60

 

After Pass 5

9

25

34

41

79

60

 

     Sorted                             unsorted

 

Pass 6 :

 Next element is 79.It is the largest element and it should be placed at last position.

9

25

34

41

79

60

 

After Pass 6

9

25

34

41

60

79

 Hence the list is sorted using insertion sort.

 We will see one more example.

 Apply Insertion sort on array A= {77,30,40,10,88,20,65,56}

Pass 1 : First element is trivially sorted.

77

30

40

10

88

20

65

56

 

77

30

40

10

88

20

65

56

 

  Sorted              unsorted

Pass 2 :

30

77

40

10

88

20

65

56

 

        Sorted                  unsorted

Pass 3 :

 30

77

40

10

88

20

65

56

 

 

After Pass 3

30

40

77

10

88

20

65

56

 

    Sorted                                          unsorted

Pass 4 :

30

40

77

10

88

20

65

56

 

 

After Pass 4

10

30

40

77

88

20

65

56

 

    Sorted                                           unsorted

Pass 5 :

10

30

40

77

88

20

65

56

 

     Sorted                                            unsorted

Pass 6 :

10

30

40

77

88

20

65

56

 

After Pass 6

10

20

30

40

77

88

65

56

 

    Sorted                                                             unsorted

Pass 7 :

10

20

30

40

77

88

65

56

 

 

After Pass 7

10

20

30

40

65

77

88

56

 

       Sorted               unsorted                                         

Pass 8 :

10

20

30

40

65

77

88

56

 

 

After Pass 8

10

20

30

40

56

65

77

88

 Hence the list is sorted using Insertion sort.

 

 

 

 C Function for Insertion Sort

 void insertionSort(int A[], int n)

 {

 int i, p, temp, j;

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

 {

 p= 0;

 temp = A[i];

 for (j=i–1; j >= 0 && !p;)

 if(temp < A[j])

 {

 A[j + 1]= A[j];

 j––;

 }

 else

 p = 1;

 A[j + 1] = temp;

 }

 return;

 }

P5 : Program to implement insertion sort.

 #include <stdio.h>

 int main()

 {

  int n, A[100], i, j, t;

   printf("Enter number of elements\n");

  scanf("%d", &n);

   printf("Enter %d integers\n", n);

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

   scanf("%d", &A[i]);

   }

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

 {

   j = i;

   while ( j > 0 && A[j] < A[j–1])

 {

  t  = A[j];

  A[j]   = A[j–1];

  A[j–1] = t;

   j––;

    }

   }

 printf("Sorted list in ascending order:\n");

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

  printf("%d\n", A[i]);

  }

   return 0;

 }

Output  :

 Enter number of elements

 5

 Enter 5 integers

 9

 4

 2

 5

 3

 Sorted  list in ascending order

 2

 3

 4

 5

 9

Complexity of Insertion Sort :

 Worst Case Complexity: In the worst case, for each i we do (i – 1) swaps inside the inner for–loop–therefore, overall number of swaps (when i goes from 2 to n in the outer for loop) is

    T(n) = 1 + 2 + 3 +...+(I – 1) +....+ n – 1

     = n (n – 1)/2

     = O(n2)

 Average case Complexity is O(n2).

 Best Case Complexity is O(n).

 

4.2.2 Finding roots of equations  

Algorithm:

Step 1: Start

Step 2: Read a,b,c

Step 3: Initialize d <- (b*b) – (4*a*c)

Step 4: Initialize r<- b/2*a

Step 5: if d>0 go to step 6

Step 6: r1 = r+(sqrt(d)/2*a) and r2 = r-(sqrt(d)/2*a)

Step 7: print roots are real and distinct first root r1, second root r2

Step 8: if d=0 go to step 9

else go to step 10

Step 9: print roots are real and equal -r

Step 10 : d= -d

Step 11: im = sqrt(d)/2*a

Step 12: print roots are imaginary, first root r+i im, second root r-i im

Step 13: stop

Program:

void main()

{

float a,b,c,r,d,r1,r2,im;

clrscr();

printf(“\n\t Quadratic Eqution\n\n Enter the coefficients\n”);

scanf(“%f%f%f”, &a,&b,&c);

d= (b*b) –(4*a*c);

r=b/2*a

if(d>0)

{

r 1 = -r + (sqrt (d)/2*a)

r2 = -r - + (sqrt (d)/2*a)

printf(“\n Roots are real and distinct \n\n first root\t: %.2f\n\n second root\t:%.2f \n”,r1,r2);

}

else if(d==0)

printf(“\n Roots are real and equal \n\n roots =:%.2f,-r);

}

else

{

d=-d;

im=sqrt(d)/2*a;

printf(“\nRoots are imaginary \n\nfirst root\t;%.2f\n\nsecond root\t:%.2f-i%.2f”,r,im,r,im);

}

getch();

}

4.2.3 Notion of order of complexity

To express the running time complexity of algorithm three asymptotic notations are available. Asymptotic notations are also called as asymptotic bounds. Notations are used to relate the growth of complex function with the simple function. Asymptotic notations have domain of natural numbers. These notations are as follows

1. Big-oh notation : Big-oh notations can be express by using ‘o’ symbol. This notation indicates the maximum number of steps required to solve the problem. This notation expresses the worst case growth of an algorithm. Consider the following diagram in which there are two functions f(x) and g(x). f(x) is more complex than the function g(x).

7

Fig. 4.7

 In the above diagram out of two function f(n) and g(n), more complex function is f(n), so need to relate its growth as compare to simple function g(n). More specifically we need one constant function c(n) which bound function f(n) at some point n0. Beyond the point ‘n0’ function c*g(n) is always greater than f(n).

 Now f(n)=Og(n)if there is some constant ‘c’ and some initial value ‘n0’. such that f(n)<=c*g(n) for all n>n0

 In the above expression ‘n’ represents the input size

 f(n) represents the time that algorithm will take

 f(n) and g(n) are non-negative functions.

 Consider the following example

8

Fig. 4.8

 In the above example g(n) is ‘’n’ and f(n) is ‘2n+1’ and value of constant is 3. The point where c*g(n) and f(n) intersect is ‘’n0’. Beyond ‘n0’ c*g(n) is always greater than f(n) for constant ‘3’. We can write the conclusion as follows

 f(n)=O g(n)    for constant ‘c’ =3 and ‘n0’=1

 such that f(n)<=c*g(n) for all n>n0

2. Big-omega notation : Big-omega notations can be express by using ‘Ω’ symbol. This notation indicates the minimum number of steps required to solve the problem. This notation expresses the best case growth of an algorithm. Consider the following diagram in which there are two functions f(n) and g(n). f(n) is more complex than the function g(n).

9

Fig. 4.9

 In the above diagram out of two function f(n) and g(n), more complex function is f(n), so need to relate its growth as compare to simple function g(n). More specifically we need one constant function c(n) which bound function f(n) at some point n0. Beyond the point ‘n0’ function c*g(n) is always smaller than f(n).

 Now f(n)=Ωg(n)if there is some constant ‘c’ and some initial value ‘n0’. such that c*g(n) <= f(n)for all n>n0

 In the above expression ‘n’ represents the input size

 f(n) represents the time that algorithm will take

 f(n) and g(n) are non-negative functions.

 Consider the following example

 In the above example g(n) is ‘2n’ and f(n) is ‘2n-2’ and value of constant is 0.5. The point where c*g(n) and f(n) intersect is ‘’n0’. Beyond ‘n0’ c*g(n) is always smaller than f(n) for constant ‘0.5’. We can write the conclusion as follows

 f(n) = Ω g(n)    for constant ‘c’ =0.5 and ‘n0’=2

 such that  c*g(n)<= f(n) for all n>n0

 

10

Fig. 4.10

 Big-theta notation : Big-theta notations can be express by using ‘Ɵ’ symbol. This notation indicates the exact number of steps required to solve the problem. This notation expresses the average case growth of an algorithm. Consider the following diagram in which there are two functions f(n) and g(n). f(n) is more complex than the function g(n).

11

Fig. 4.11

 In the above diagram out of two function f(n) and g(n), more complex function is f(n), so need to relate its growth as compare to simple function g(n). More specifically we need one constant function c1 and c2 which bound function f(n) at some point n0. Beyond the point ‘n0’ function c1*g(n) is always smaller than f(n) and c2*g(n) is always greater than f(n).

 Now f(n) = g(n) if there is some constant ‘c1 and c2’ and some initial value ‘n0’. such that c1*g(n) <= f(n)<=c2*g(n)for all n>n0

 In the above expression ‘n’ represents the input size

 f(n) represents the time that algorithm will take

 f(n) and g(n) are non-negative functions.

 f(n) = g(n) if and only if f(n)=O g(n) and f(n)=Ω g(n)

 Consider the following example

12

Fig. 4.12

 In the above example g(n) is ‘2n’ and f(n) is ‘3n-2’ and value of constant c1 is 0.5 and c2 is 2. The point where c*g(n) and f(n) intersect is ‘’n0’. Beyond ‘n0’ c1*g(n) is always smaller than f(n) for constant ‘0.5’ and c2*g(n) is always greater than f(n) for constant ‘2’. We can write the conclusion as follows

 f(n)=Ω g(n)    for constant ‘c1’ =0.5 , ‘c2’ = 2 and ‘n0’=2

 such that  c1*g(n)<= f(n)<=c2*g(n) for all n>n0

 

References:

  1. The C Programming Language. 2nd Edition Book by Brian Kernighan and Dennis Ritchie
  2. C Programming: A Modern Approach Book by Kim N. King
  3. C Programming Absolute Beginner’s Guide book by S.D Perry

 

 


Index
Notes
Highlighted
Underlined
:
Browse by Topics
:
Notes
Highlighted
Underlined