0 Voti positivi0 Voti negativi

6 visualizzazioni96 pagineIT

May 03, 2013

© Attribution Non-Commercial (BY-NC)

DOC, PDF, TXT o leggi online da Scribd

IT

Attribution Non-Commercial (BY-NC)

6 visualizzazioni

IT

Attribution Non-Commercial (BY-NC)

- Class 11
- Online Convex Hull
- Interview Questions
- Interactive Dimensioning of Parametric Models
- Singly Linked List Operation
- artificial intelligence
- c Programmings
- c Puzzle Answers
- ADS Manual
- data stuture record.doc
- Huff Man
- Binary Search Tree
- TR Sorting
- Learning J
- Lowest Common Ancestor
- Cs2208 Lab Manua
- Assignment4--BinaryTrees
- DS Syllabus
- Fastexp Copy
- Cs1201 Design and Analysis of Algorithm

Sei sulla pagina 1di 96

INTRODUCTION

This chapter introduces the subject of data structures and presents a detail description of data

organization and data structures along with a discussion of the different operations which are

applied to these data structures. We will also introduce the notion of an algorithm and its

complexity, and also the time -space tradeoff that may occur in choosing a particular algorithm and

data structure for a given problem.

BASIC TERMINOLOGY; ELEMENTARY DATA ORGANIZATION

Data are simply values or sets of values . A data item refers to a single unit of values. Data items

that are divided into sub items are called group items; those that are not are called elementary

items. Collections of data are frequently organized into a hierarchy of fields, records and files. In

order to make these terms more precise we introduce some additional terminology.

An entity is something that has certain attributes or properties which may be assigned values. The

values themselves may be either numeric or nonnumeric.

DATA STRUCTURES

Data may be organized in many ways ; the logical or mathematical model of a particular

organization of data is called a data structure. The choice of a particular data model depends on

two considerations. First, it must be rich enough in structure to mirror the actual relationships of

the data in the real world. On the other hand, the structure should be simple enough that one can

effectively process the data when necessary. Some of the data structures commonly used are :

Arrays, Linked Lists, Stacks, Queues, Trees etc.

These data structures are discussed in detail later in the chapter.

DATA STRUCTURE OPERATIONS

The data appearing in our data structures are processed by means of certain operations. In fact,

the particular data structure that one chooses for a given situation depends largely on the

frequency with which specific operations are performed. This section introduces the reader to some

of the most frequently used of the operations.

The following four operations play a major role in this text:

Traversing: Accessing each record exactly once so that certain items in the

record may be processed. ( This accessing and processing is sometimes called visiting the

record.)

Searching: Finding the location of the record with a given key value ,

or finding the locations of all records which satisfy one or more conditions.

Inserting: Adding a new record to the structure.

Deleting: Removing a record from the structure.

Sometimes two or more of the operations may be used in a given situation; e.g., we may want to

delete the record with a given key, which may mean we first need to search for the location of the

record .

The following two operations which are used in a given special situations, will also be considered:

Sorting: Arranging the records in some logical order (e.g., alphabetically according to some NAME

key, or in numerical order according to some NUMBER key, such as social security number or

account number)

Merging: Combining the records in two different sorted files into a single sorted file .

ALGORITHMS : COMPLEXITY, TIME-SPACE TRADEOFF

An algorithm is well-defined list of steps for solving a particular problem. One major purpose of this

text is to develop efficient algorithms for the processing of our data. The time and space it uses are

two major measures of the efficiency of an algorithm. The complexity of an algorithm is the

function which gives the running time and/or space in terms of the input size.

Each of our algorithms will involve a particular data structure. Accordingly, we may not always be

able to use the most efficient algorithm, since the choice of data structure depends on many

things, including the type of data and the frequency with which various data operations are

applied. Sometimes the choice of data structure involves a time-space tradeoff: by increasing the

amount o space for storing the data, one may be able to reduce the time needed for processing the

data, or vice versa.

MATHEMATICAL NOTATION AND FUNCTIONS

This section gives various mathematical functions which appear very often in the analysis of

algorithm and in computer science in general, together with their notation.

Floor and Ceiling Functions

Let x be any real number. Then x lies between two integers called the floor and the ceiling of x .

Specifically,

, called the floor of x, denotes the greatest integerx- that does not exceed x.

, called the ceiling of x, denotes the leastx integer that is not less than x.

= x-If x is itself an integer, then . x + 1 = x-; otherwise x

Remainder Function : Modular Arithmetic

Let k be any integer and let M be a positive integer. Then k(mod M)

(read k modulo M) will denote the integer remainder when k is divided by M. More exactly k(mod

m) is the unique integer r such that k = Mq + r where 0<= r< M

When k is positive, simply divide k by M to obtain the remainder r. Thus 25(mod 7) = 4, 25(mod 5)

= 0, 35(mod 11) = 2

INTEGER AND ABSOLUTE VALUE FUNCTIONS

Let x be any real number. The integer value of x, written INT(x), converts x into an integer by

deleting (truncating) the fractional part of the number. Thus 5) = 2, INT(-8.5) = -8-INT(3.14) =

3, INT(

Observe that according to whether x isx- or INT(x) = xINT(x) = positive or negative.

The absolute value of the real number x, written ABS(x) or | x |, is 0,-defined as the greater of x

or -x. hence ABS(0) = 0, and ,for x ABS(x) = x or ABS(x) = -x, depending on whether x is positive

or negative Thus,

|-15| = 15, |7| = 7, |-3.33| = 3.33, |2.23| = 2.23

We 0, | x | is-note that | x | = | - x | and, for x positive.

Summation Symbol ; Sums

Here we introduce the (the Greek letter sigma).-summation symbol. Consider a sequence

a1,a2,a3,.Then the sums

a1 + a2 + a3 +.+an and am + am+1 +.+ an

will be denoted, respectively, by

n n

aj- aj and -

j=1 j=m

The letter j in the above expressions is called a dummy index or dummy variable. Other letters

frequently used as dummy variables are i, k, s and t.

FACTORIAL FUNCTION

The product of the positive integers from 1 to n, inclusive, is denoted by n! (read n factorial ).

That is, n! = 1.2.3. .(n - 2)(n - 1)n

It is also convenient to define 0! = 1.

PERMUTATIONS

A permutation of a set of n elements is an arrangement of the elements in a given order. For

example, the permutations of the set consisting of the elements a, b, c are as follows:

abc, acb, bac, bca, cab, cba

There are n! permutations of a set of n elements.

COMPLEXITY OF ALGORITHM

The analysis of algorithms is a major task in computer science. In order to compare algorithms, we

must have some criteria to measure the efficiency of our algorithms. This section discusses this

important topic.

Suppose M is an algorithm, and suppose n is the size of the input data. The time and space used

by the algorithm M are the two main measures for the efficiency of M. The time and space is

measured by counting the number of key operations - in sorting and searching algorithms, for

example, the number of comparisons. That is because key operations are so defined that the time

for the other operations is much less than or at most proportional to the time for the key

operations. The space is measured by counting the maximum of the memory needed by the

algorithm.

The complexity of an algorithm M is the function f(n) which gives the running and/or storage space

requirement of an algorithm in terms of the input data. Frequently, the storage space required by

an algorithm is simply a multiple of the data size n. Accordingly, unless otherwise stated or

implied, the term complexity shall refer to the running time of the algorithm.

The following example illustrates that the function f(n), which gives the running time of an

algorithm, depends not only on the size n of the input data but also on the particular data.

EXAMPLE

Suppose we are given an English short story TEXT, and suppose we want to search through TEXT

for the first occurrence of a given 3- letter word W. If W is the 3 -letter word the, then it is likely

that W occurs near the beginning of TEXT, so f(n) will be small. On the other hand, if W is the 3-

letter word zoo, then W may appear in TEXT at all, so f(n) will be large.

The above discussion leads us to the question of finding the complexity function f(n) for certain

cases. The two cases one usually investigates in complexity theory are as follows:

Worst case: the maximum value of f(n) for any possible input

Average case: the expected value of f(n)

Suppose we also consider the minimum possible value of f(n), called the best Case.

The analysis of the average case assumes a certain probabilistic distribution for the input data; one

such assumption might be that all possible permutation of an input data set are equally likely . The

average case also uses the following concept in probability theory. Suppose the number n1, n2, n3,

..,nk occur with respective probabilities p1, p2, p3 ,pk. Then the exception or average value E is

given by

E = n1p1 + n2p2 + .+ nkpk

DETAILED DESCRIPTION OF VARIOUS DATA STRUCTURES

ARRAYS

The simplest type of data structure is a linear (or- one - dimensional) array. By a linear array, we

mean a list of finite number n of similar data elements referenced by a set of an consecutive

numbers, usually 1, 2, 3, .,n. If we choose the name A for the array, then the elements of A are

denoted by the subscript notation

a1, a2, a3, . an

or by parenthesis notation

A(1), A(2), A)3), ..,A(n)

Or by the bracket notation

A[1], A[2], A[3], ..,A[n]

Regardless of the notation, the number K in A[K] is called a subscript and A[K] is called a

subscripted variable.

ONE DIMENSIONAL ARRAY

An array is a collection of similar data elements. An array is also called linear data structures.

There exists a linear relationship between the array elements. The array elements lie in the

computer memory in a linear fashion. The syntax to define an array is :

Data type array name[size];

1 2 3 4 5 6 7

2128 2143 4348 4361 4538 5423 5438

Horizontal representation of an array

RAVERSING ONE DIMENSIONAL ARRAY

Suppose we have an array M that is collection of integer type in the computer memory. If we visit

each and every element in M then this visiting process is called traversing.

TRAVERSING ALGORITHM

The program segment to illustrate the traversing algorithm.

// Array_T.C

/* Traversing a linear array */

/* ARRAY_T.C */

# include<stdio.h>

void traversing_array(int *, int, int);

void input(int *, int, int);

/* Definition of the function*/

void traversing_array(int linear_array[], int l_b, int u_b)

{

int counter;

for(counter = l_b; counter<=u_b; counter++)

{

printf("\n Element at position: %d is %d ", counter, linear_array[counter]);

}

}

/* Defintion of the function*/

void input(int array[], int l_b, int u_b)

{

int counter;

for(counter = l_b; counter<= u_b; counter++)

{

printf("\n Input value for the: %d: ", counter);

scanf("%d", &array[counter]);

}

}

/* Definition of the function */

void main()

{

int a[100];

int lb, ub;

printf("\n Lower limit of the array:");

scanf("%d", &lb);

printf("\n Upper limit of the array:");

scanf("%d", &ub);

input(a, lb, ub);

traversing_array(a,lb,ub);

}

INSERTION IN A ONE DIMENSIONAL ARRAY

It can be visualized that for inserting an element in one - dimensional array, one has to shift all the

elements one position down.

INSERTION ALGORITHM

The program illustrated below implements the above algorithm

/* INSERTING AN ELEMENT INTO LINEAR ARRAY AT SPECIFIED POSITION */

/* ARRAY_I.C */

# include<stdio.h>

int insert_array(char *, int, int, char);

void input(char *, int );

void display(char *, int );

/* Definition of the function */

int insert_array(char array[], int number, int position, char element)

{

int temp = number;

while( temp >= position)

{

array[temp+1] = array[temp];

temp --;

}

array[position] = element;

number = number +1 ;

return(number);

}

/* INPUT FUNCTION TO READ DATA */

void input(char array[], int number)

{

int i;

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

{

fflush(stdin);

printf("\n Input value for: %d: ", i);

scanf("%c", &array[i]);

}

}

/* OUTPUT FUNCTION TO PRINT ON THE CONSOLE */

void display(char array[], int number)

{

int i;

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

{

printf("\n Value at the position: %d: %c ", i, array[i]);

}

}

/* main function */

void main()

{

int number;

char array[100];

int position;

char element;

fflush(stdin);

printf("\n Input the number of element into the LIST: ");

scanf("%d", &number);

fflush(stdin);

input(array, number);

printf("\n Entered list as follows:\n");

fflush(stdin);

display(array,number);

fflush(stdin);

printf("\n Input the position where you want add a new

data:");

scanf("%d", &position);

fflush(stdin);

printf("\n Input the value for the position:");

scanf("%c", &element);

number = insert_array(array,number,position,element);

display(array,number);

getch();

}

DELETION FROM ONE DIMENSIONAL ARRAY

Deleting an element or information from the end of an array is simple but deleting an element from

some other position is difficult and requires moving all the element up-word to fill -up the gap into

the array. Before deleting an element from an array one should go through the following points.

Delete an element if is known then find whether is in the array or not.

Delete an element if its value is known. The value is searched in the array.

Update the array.

Deletion Algorithm

Program to implement the above algorithm.

/* DELETING FROM A LINEAR ARRAY AT SPECIFIED POSITION */

# include<stdio.h>

# define s 20

char employ[s][s];

int delete_array(char employ[s][s], int, int, char *);

void input(char emply[s][s], int );

void display(char employ[s][s], int );

/* Definition of the function */

int delete_array(char employ[s][s], int number, int position, char element[])

{

int temp = position;

element = employ[position];

printf("\n Information which we have to delete: %s", element);

while( temp <= number-1)

{

*employ [temp] = *employ[temp+1];

temp ++;

}

number = number - 1 ;

return(number);

}

void input(char employ[s][s], int number)

{

int i;

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

{

fflush(stdin);

printf("\n Input value for: %d: ", i);

gets(employ[i]);

}

}

void display(char employ[s][s], int number)

{

int i;

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

{

printf("\n Value at the position: %d: %s", i, employ[i]);

}

}

/* main function */

void main()

{

int number;

int position;

char element[s];

printf("\n Input the number of elements in the array:");

scanf("%d", &number);

fflush(stdin);

input(employ, number);

printf("\n Entered list is as follows:\n");

display(employ, number);

fflush(stdin);

printf("\n Input the position from where you want delete an element:");

scanf("%d", &position);

number = delete_array(employ, number, position, element);

display(employ,number);}

If in a list same information happens to be more than one place then the repeated information is

called duplicate. The removal of such duplicates is very necessary in some application. Because if

some one is accessing an information from a list but does not know about its duplication and

modifying the such information in one place the inconsistency take place.

The algorithm to remove duplicates from a list is as follows:

Duplicate removal Algorithm

Program to implement duplicate removal algorithm

/* DELETING DUPLICATES FROM A LINEAR ARRAY*/

# include<stdio.h>

int status ;

int dup;

int duplicate_array(int *, int);

void input(int *, int );

void display(int *, int );

/* Definition of the function */

int duplicate_array(int array[], int number)

{

int i, j, k;

status = 0;

dup = number;

for(i = 0; i< number-1; i++)

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

{

if(array[i] == array[j])

{

number = number - 1 ;

for(k = j; k<number; k++)

array[k] = array[k+1];

status = 1;

j = j - 1;

}

}

if( status ==0)

printf("\n No duplicate is found");

return(dup-number);

}

/* Input function to read data */

void input(int array[], int number)

{

int i;

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

{

printf("Input value for: %d: ", i+1);

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

}

}

/* Output function */

void display(int array[], int number)

{

int i;

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

{

printf("\n Value at the position: %d: %d", i+1, array[i]);

}

}

/* main function */

void main()

{

int number;

int array[100];

int n;

printf("\n Input the number of elements in the list: ");

scanf("%d", &number);

input(array, number);

printf("\n Entered list is as follows:\n");

display(array,number);

n = duplicate_array(array,number);

printf("\nNumber of duplicate elements in the list are: %d", n);

printf("\nAfter removing duplicates from the list, the list is as

follows:");

display(array,number-n);

}

SEARCHING

Suppose a specific INFO information is given in an array. Searching refers to the operation of

finding the location of the INFO in an array or output some massage if INFO does not exists in the

array. The search is said to be successful if INFO appears in the array else it is called unsuccessful.

Some times it is required to add INFO in the array if do not exist.

For more discussion on sorting, searching, and merging, please go through Chapter 4.

Algorithm to find the smallest and largest element in a list:

Algorithm to find Smallest and Largest

Program implementing above algorithm:

/* SEARCHING FOR LARGEST AND SMALLEST ELEMENTS IN A

LINEAR ARRAY */

# include<stdio.h>

int s;

int small, big, temp;

int search_array(int *, int);

void input(int *, int );

void display(int *, int );

/* Definition of the function */

int search_array(int array[], int number)

{

big = small = array[0];

temp = 0;

while(temp < number)

{

if(array[temp] > big)

{

big = array[temp] ;

}

else if(array[temp] < small)

{

small = array[temp];

}

temp ++;

}

s = small;

return(big);

}

/* Input function */

void input(int array[], int number)

{

int i;

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

{

printf("Input value for : %d: ",i+1);

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

}

}

/* Output function */

void display(int array[], int number)

{

int i;

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

{

printf("\n Value at the position: %d: %d", i+1, array[i]);

}

}

/* main function */

void main()

{

int number,big;

int array[100];

printf("\n Input the number of elements in the list:");

scanf("%d", &number);

input(array, number);

printf("\n Entered list is as follows:\n");

display(array,number);

big = search_array(array,number);

printf("\nLargest number in the array is : %d", big);

printf("\nSmallest number in the array is : %d", s);

}

MULTI DIMENSIONAL ARRAYS

Most of the programming languages permit two, three, four, five and more dimensional arrays

where an element is referenced by more than one subscript. If an array is two - dimensional then

two subscripts are used to reference an element in the array. Similarly, if the array is a three -

dimensional then three subscripts are used to reference an element of the array. C, C++, and

Visual C/C++ languages permit 1, 2, 3, 4 or more dimensional arrays, where BASIC language

permit only 1, 2 and 3 dimensional arrays. The advanced versions of BASIC, Visual BASIC permit

arrays as permitted by C, C++ and Visual C/C++ languages.

Row\Column

0 1 2

0 11 33 22

1 22 44 11

2 33 55 99

3 44 66 88

4 55 66 77

TWO DIMENSIONAL ARRAYS

Let Mat is a two dimensional array with Row number of rows and Col number of columns. Then one

may define array Mat as a collection of Row x Col information . Each element of the array Mat is

accessed by specified pairs of integers called subscripts. If I and J are integers and are used to

access information from a two - dimensional array Mat, then there should be following relations

among subscript variable I and J, and rows and columns maximum limit.

I0 < Row

For C, C++, and Visual C/C++ languages

J0 < Col

Row I 1

For other popular languages e.g. FORTRAN etc.

J 1 Col

Two-dimensional arrays are called Matrices in mathematics and table in business applications.

There is a standard way for drawing a two dimensional Row x Col array Mat. The elements of Mat

form a rectangular array with Row rows and Col columns. The element Mat[I][J] appears in row I

and column J. A row is a horizontal list of elements and a column is a vertical list of elements. In

the field of database a row is called a tuple.

COLUMN -------

Mat[0][0] Mat[0][1] Mat[0][2] Mat[0][3] Mat[0][4]

Mat[1][0] Mat[1][1] Mat[1][2] Mat[1][3] Mat[1][4]

Mat[2][0] Mat[2][1] Mat[2][2] Mat[2][3] Mat[2][4]

Mat[3][0] Mat[3][1] Mat[3][2] Mat[3][3] Mat[3][4]

Mat[4][0] Mat[4][1] Mat[4][2] Mat[4][3] Mat[4][4]

Mat[5][0] Mat[5][1] Mat[5][2] Mat[5][3] Mat[5][4]

Two dimensional representation of an array

TRAVERSING TWO DIMENSIONAL ARRAYS

Traversing of a two-dimensional array can be classified into two categories, depending upon the

two types of representation:

(i) Column major order

(ii) Row major order

Algorithm to traverse a two dimensional array in row major order

Algorithm to traverse a two dimensional array in column major order

Program showing the traversing in a two dimensional array

/* TRAVERSING A TWO DIMENSIONAL ARRAY */

# include<stdio.h>

int i, j;

float mat[10][10];

void Traverse ( int, int);

void input( int, int);

/* Display function */

void Traverse (int row, int col)

{

printf("\n Traversing in row major order\n");

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

{

for( j = 0; j < col; j++)

{

printf("\n 0x%x", &mat[i][j]);

printf(" %f", mat[i][j]);

}

printf("\n");

}

printf("\n Traversing in column major order\n");

for(j = 0; j < col; j++)

{

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

{

printf("\n 0x%x", &mat[i][j]);

printf(" %f", mat[i][j]);

}

printf("\n");

}

printf("\n Traversing in row major order\n");

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

{

for(j = 0; j < col; j++)

{

printf(" mat[%d][%d] = ", i, j);

printf("%f", mat[i][j]);

}

printf("\n");

}

printf("\n Traversing in column major order\n");

for(j = 0; j < col; j++)

{

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

{

printf(" mat[%d][%d] = ", i, j);

printf("%f", mat[i][j]);

}

printf("\n");

}

}

/* Input function */

void input(int row, int col)

{

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

{

for(j = 0 ; j<col; j++)

{

printf("\nInput Value for : %d: %d: ",i+1, j+1);

scanf("%f", &mat[i][j]);

}

}

}

/* main function */

void main()

{

int r,c;

printf("\n Input the number of rows:");

scanf("%d", &r);

printf(" Input the number of cols:");

scanf("%d", &c);

input(r, c);

Traverse(r, c);

}

ALGEBRA OF MATRICES

ADDITION OF MATRICES

Let A and B two matrices of the same order. Then their sum, A+B is defined as a matrix, each

element of which is summation of the corresponding elements of A and B. For example, if we have

1 2 3

A = 4 5 6

7 8 9

10 11 12

and

11 22 33

B = 4 55 66

7 88 99

10 11 12

1+11 2+22 3+33

then A + B = 4+4 5+55 6+66

7+7 8+88 9+99

10+10 11+11 12+12

12 24 36

or A +B = 8 60 72

14 96 108

20 22 24

If A = [aij] and B = [bij] then A+B = [aij] + [bij]

The algorithm to find the summation of two matrices is illustrated in Fig. below.

Algorithm to add two matrices

Program to implement above algorithm to add two matrices:

/* Add Tow Matrices */

# include<stdio.h>

# include<stdlib.h>

# define row 10

# define col 10

int i, j;

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

void mat_add( float mat1[row][col], int, int,

float mat2[row][col], int, int,

float mat_res[row][col]);

void display(float mat[row][col], int, int);

void input(float mat[row][col], int , int);

/* Function mat_add */

void mat_add(float mat1[row][col], int row1, int col1,

float mat2[row][col], int row2, int col2,

float mat_res[row][col])

{

int i, j;

if((row1 == row2) && (col1 == col2))

{

printf("\n Addition is possible and Result is as follows\n");

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

for(j = 0; j<col1; j++)

mat_res[i][j] = mat1[i][j]+mat2[i][j];

display(mat_res,row1,col1);

}

else

printf("\n Addition is not possible");

exit(0);

}

/* Output function */

void display(float mat[row][col], int r, int c )

{

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

{

for(j = 0; j < c; j++)

{

printf(" %f", mat[i][j]);

}

printf("\n");

}

}

/* Input function */

void input(float mat[row][col], int r, int c)

{

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

{

for(j = 0 ; j < c; j++)

{

printf("Input Value for : %d: %d: ", i+1, j+1);

scanf("%f", &mat[i][j]);

}

}

}

/* main function */

void main()

{

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

printf("\n Input the row of the matrix->1:");

scanf("%d", &row1);

printf(" Input the col of the matrix->1:");

scanf("%d", &col1);

printf("\n Input data for matrix-> 1\n");

input(mat1, row1, col1);

printf("\n Input the row of the matrix ->2:");

scanf("%d", &row2);

printf("\n Input the col of the matrix->2:");

scanf("%d", &col2);

printf("\n Input data for matrix-> 2\n");

input(mat2, row2, col2);

printf("\n Entered Matrix First is as follows:\n");

display(mat1,row1,col1);

printf("\n Entered Matrix Two is as follows:\n");

display(mat2,row2,col2);

mat_add(mat1, row1, col1, mat2, row2, col2, mat_res);

}

SUBTRACTION OF MATRICES

The difference of two matrices is a matrix, each element of which is obtained by subtracting the

elements of the second matrix from the corresponding element of the first matrix. If A and B are

two matrices then the difference of B and A is noted by B - A will be defined by:

B - A = [bij - aij]

For example, if

11 12 3

A = 41 15 6

71 8 19

10 11 12

and

1 22 33

B = 4 55 6

7 88 9

100 11 12

11-11 22-12 33-3

then B-A = 4-41 55-15 6-6

7-71 88-8 9-19

100-10 11-11 12-12

0 10 30

B-A = -37 40 0

-64 80 -10

90 0 0

Algorithm to Subtract two matrices

Program to implement above algorithm

/* Subtraction of two Matrices */

# include<stdio.h>

# include<stdlib.h>

# define row 10

# define col 10

int i, j;

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

void mat_sub( float mat1[row][col], int, int,

float mat2[row][col], int, int,

float mat_res[row][col]);

void display(float mat[row][col], int, int);

void input(float mat[row][col], int , int);

/* Function mat_sub */

void mat_sub(float mat1[row][col], int row1, int col1,

float mat2[row][col], int row2, int col2,

float mat_res[row][col])

{

if(( row1 == row2) && (col1 == col2))

{

printf("\n Subtraction is possible and Result is as follows\n");

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

for(j = 0; j < col1; j++)

mat_res[i][j] = mat1[i][j] - mat2[i][j];

display(mat_res,row1,col1);

}

else

printf("\n Subtraction is not possible");

exit(0);

}

/* Output Function */

void display(float mat[row][col], int r, int c )

{

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

{

for(j = 0; j < c; j++)

{

printf(" %f", mat[i][j]);

}

printf("\n");

}

}

/* Input function */

void input(float mat[row][col], int r, int c)

{

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

{

for(j = 0 ; j<c; j++)

{

printf("Input Value for : %d: %d: ", i+1, j+1);

scanf("%f", &mat[i][j]);

}

}

}

/* main function */

void main()

{

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

printf("\n Input the row of the matrix->1:");

scanf("%d", &row1);

printf("\n Input the col of the matrix->1:");

scanf("%d", &col1);

printf(" Input data for matrix-> 1\n");

input(mat1, row1, col1);

printf("Input the row of the matrix ->2:");

scanf("%d", &row2);

printf(" Input the col of the matrix->2:");

scanf("%d", &col2);

printf(" Input data for matrix-> 2\n");

input(mat2, row2, col2);

printf("\n Entered Matrix First is as follows:\n");

display(mat1,row1,col1);

printf("\n Entered Matrix Two is as follows:\n");

display(mat2,row2,col2);

mat_sub(mat1,row1,col1,mat2,row1,col2,mat_res);

display(mat_res,row2,col2);

}

MULTIPLICATION OF TWO MATRICES

The product of two matrices A and B is possible if the numbers of columns in A is equal to the

number of rows in B or number of rows in A is equal to the number of columns in B. Let A = [aij]

be an m x n matrix and p matrix. Then the productB = [bij] be an n p say C = [cij]. WhereA.B

of these matrices is of the order of m

cij = ail . blj + ai2 . b2j + + ain . bnj

n

aik . bkj-cij =

k = 1

1 -2 3

A = 2 3 -1

-3 1 2

1 0 2

B = 0 1 2

1 2 0

Multiplying row of 1st matrix and column of 2nd matrix

1*1+(-2)*0+3*1 1*0+(-2)*1+3*2 1*2+(-2)*2+3*0

A. B = 2*1+3*0+(-1)*1 2*0+3*1+(-1)*2 2*2+3*2+(-1)*0

(-3)*1+1*0+2*1 (-3)*0+1*1+2*2 (-3)*2+1*2+2*0

1-0+3 0-2+6 2-4+0

A. B = 2+0-1 0+3-2 4+6-0

-3+0+2 -0+1+4 -6+2+0

4 4 -2

A.B = 1 1 10

-1 5 -4

Algorithm to multiply two matrices

Program to implement above algorithm to multiply two matrices

/* Multiply Two Matrices */

/* MULT_MAT.C */

# include<stdio.h>

# include<stdlib.h>

# define row 10

# define col 10

int i, j;

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

void mat_mult( float mat1[row][col], int, int,

float mat2[row][col], int, int,

float mat_res[row][col]);

void display(float mat[row][col], int, int);

void input(float mat[row][col], int , int);

/* function to multiply two matrices */

void mat_mult( float mat1[row][col], int row1, int col1,

float mat2[row][col], int row2, int col2,

float mat_res[row][col])

{

int i, j, k;

if(col1 == row2)

{

printf("\n Multiplication is possible and Result is as follows\n");

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

for(j=0; j<col2; j++)

{

mat_res[i][j] = 0;

for(k = 0; k < col1; k ++)

{

mat_res[i][j] += mat1[i][k] * mat2[k][j];

}

}

display(mat_res, row1, col2);

}

else

printf("\n Multiplication is not possible");

exit(0);

}

/* Output function */

void display(float mat[row][col], int r, int c )

{

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

{

for( j = 0; j < c; j++)

{

printf(" %f", mat[i][j]);

}

printf("\n");

}

}

/* Input function */

void input(float mat[row][col], int r, int c)

{

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

{

for( j = 0 ; j<c; j++)

{

printf("Input Value for : %d: %d: ", i+1, j+1);

scanf("%f", &mat[i][j]);

}

}

}

/* main function */

void main()

{

int row1, col1;

int row2, col2;

float mat1[row][col];

float mat2[row][col];

float mat_res[row][col];

printf("\n Input the row of the matrix->1:");

scanf("%d", &row1);

printf("\n Input the col of the matrix->1:");

scanf("%d", &col1);

printf("\n Input data for matrix-> 1\n");

input(mat1, row1, col1);

printf("\n Input the row of the matrix ->2:");

scanf("%d", &row2);

printf("\n Input the col of the matrix->2:");

scanf("%d", &col2);

printf("\n Input data for matrix-> 2\n");

input(mat2, row2, col2);

printf("\n Entered Matrix First is as follows:\n");

display(mat1,row1,col1);

printf("\n Entered Matrix Two is as follows:\n");

display(mat2,row2,col2);

mat_mult(mat1 ,row1 ,col1, mat2, row2, col2, mat_res);

}

TRANSPOSE OF A MATRIX

A transpose of a matrix is obtained by interchanging the rows with corresponding columns of a

given matrix. A transpose of matrix A generally n then after transposingis denoted by AT. If

matrix A is an m it we will get m matrix AT. If A = [aij] then AT = [aji].an n

For example :

1 2 3 4

A = 5 6 7 8

9 10 11 12

Then transpose of A is:

1 5 9

2 6 10

A^T = 3 7 11

4 8 12

Algorithm to transpose a matrix

Program to transpose a matrix

/* Transpose of a matrix */

# include<stdio.h>

int i, j;

int value;

int mat[10][10];

void display(int, int);

void display_o( int transp[10][10],int, int);

void input( int transp[10][10],int, int);

void transpose( int transp[10][10],int, int);

/* Transpose function */

void transpose(int transp[10][10], int row, int col)

{

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

{

for(j = 0; j < col; j++)

{

mat[i][j] = transp[j][i] ;

}

}

}

/* Output function */

void display(int row, int col)

{

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

{

for(j = 0; j < col; j++)

{

printf(" %d", mat[i][j]);

}

printf("\n");

}

}

/* Output function */

void display_o(int transp[10][10], int row, int col)

{

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

{

for(j = 0; j < col; j++)

{

printf(" %d", transp[i][j]);

}

printf("\n");

}

}

/* Input function */

void input(int transp[10][10], int row, int col)

{

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

{

for(j = 0 ; j<col; j++)

{

printf("Input Value for : %d: %d: ", i+1,j+1);

scanf("%d", &value);

transp[i][j] = value;

}

}

}

/* main function */

void main()

{

int row,col;

int transp[10][10];

printf("\n Input the number of rows:");

scanf("%d", &row);

printf(" Input number of cols:");

scanf("%d", &col);

input(transp, row, col);

printf("\n Entered Matrix is as follows:\n");

display_o(transp, row, col);

transpose(transp,col,row);

printf("\n Transpose of above matrix is as follows:\n");

display(col, row);

}

INVERSE OF A MATRIX

If A and B are two matrices of the same order such that

A.B = B.A = U[ Where U is a unity matrix]

Then B is called the inverse of A and is denoted as B = A-1 , to Possesses an inverse of matrix A ,

the matrix should be a nonsingular:

0- | A |

If A is a matrix and B be its inverse, then A.B = U

Taking determinant of both sides

| A.B | = | U |

| A |.| B | = | U |

|-From this relation it is clear that |A| U | that is matrix A is non-Singular . There are two

techniques to find inverse of matrix. Inverse of matrix with the help of adjoin matrix that is

A . (Adjoin A) = |A| . U

A . (Adjoin A) = |A| . U

Or A . 1 . (Adjoin A) = U

| A |

and A . A-1 = U

that is

A-1 = 1 . (Adjoin A)

| A |

(ii) Inverse of a matrix from elementary matrices

If A is reduced to U by elementary row transformation then E . A =U

Where E = En En-1.E2E1

Then E = A-1 = Elementary matrix.

Algorithm for inverse of a matrix

Program to implement the given algorithm for inverse of a matrix

/* Find Inverse of a Matrix */

# include<stdio.h>

int i, j;

void display( int, int, float mat[10][10],float mat1[10][10]);

void input( int, int, float mat[10][10],float mat1[10][10]);

Inverse_Mat(int , int, float mat[10][10],float mat1[10][10]);

void swap(int, int, int, float mat[10][10],float mat1[10][10]);

/* This function exchange two rows of a matrix */

void swap( int row1,int row2, int col, float mat[10][10],float mat1[10][10])

{

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

{

float temp = mat[row1][i];

mat[row1][i] = mat[row2][i];

mat[row2][i] = temp;

temp = mat1[row1][i];

mat1[row1][i] = mat1[row2][i];

mat1[row2][i] = temp;

}

}

/* This function find inverse of matrix */

int Inverse_Mat(int row1, int col1, float mat[10][10],float mat1[10][10])

{

int singular = 0;

int r, c;

for(r = 0;( r < row1)&& !singular; r++)

{

if( mat[r][r] ) /* Diagonal element is not zero */

for(c = 0; c < col1; c++)

if( c == r)

{

/* Make all the elements above and below the current principal diagonal element zero */

float ratio = mat[r][r];

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

{

mat[r][i] /= ratio ;

mat1[r][i] /= ratio;

}

}

else

{

float ratio = mat[c][r] / mat[r][r];

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

{

mat[c][i] -= ratio * mat[r][i];

mat1[c][i] -= ratio * mat1[r][i];

}

}

else

{

/* If principal diagonal element is zero */

singular = 1;

for(c = (r+1); (c < col1) && singular; ++c)

if(mat[c][r])

{

singular = 0;

/* Find non zero elements in the same column */

swap(r,c,col1, mat, mat1);

--r;

}

}

}

return(!singular);

}

/* To print output this is used */

void display( int row, int col, float mat[10][10],float mat1[10][10])

{

printf("\n");

/* Output of inverse Matrix */

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

{

for( j = 0; j < col; j++)

{

printf(" %f", mat1[i][j]);

}

printf("\n");

}

}

/* input function */

void input( int row, int col, float mat[10][10],float mat1[10][10])

{

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

{

for( j = 0 ; j<col; j++)

{

printf("Input Value for: %d: %d: ", i+1, j+1);

scanf("%f", &mat[i][j]);

mat1[i][j] = 0;

}

mat1[i][i] = 1;

}

printf("\n Entered Matrix is as follows:\n");

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

{

for( j = 0; j < col; j++)

{

printf(" %f", mat[i][j]);

}

printf("\n");

}

}

/* main function */

void main()

{

int R, C;

float mat[10][10];

float mat1[10][10];

printf("\n Input number of rows:");

scanf("%d", &R);

printf(" Input number of cols:");

scanf("%d", &C);

input(R,C, mat, mat1);

Inverse_Mat(R,C, mat, mat1);

printf("\n Inverse of above matrix is as follows:\n ");

display(R,C, mat, mat1);

}

RANK OF A MATRIX

The rank of a matrix r is defined if It has at least one non-zero minor of order r.Every minor of

order higher than r is zero.

To find the rank of matrix reduce the given matrix to upper triangular form. Rank of the matrix is

equal to the number of non-zero roes. A non-zero must contain at least one non-zero number.

For example:-

1 4 5

A = 2 6 8

3 7 22

Step 1 : Subtract 2 times of the first row from the second row that is

R2 - 2*R1 and 3 times of the first row from the third row that is R3 -3*R1.

1 4 5

0 -2 -2

0 -5 7

Taking -2 common from the second row we get

1 4 5

0 1 1 -1/2R2

0 -5 7

Adding 5 times the second row into the third row that is R3 + 5*R2

1 4 5

0 1 1

0 0 12

Thus from the above resulting matrix it is clear that there is no non - zero row in the matrix hence

the rank of the matrix A is 3.

The algorithm to find rank of a matrix is given below:

Algorithm to find rank of a matrix

Program to implement above algorithm to find the rank of a matrix

/* Find Rank of a Matrix */

# include<stdio.h>

int R,C;

int i, j;

int mat[10][10];

void display( int, int);

void input( int, int);

int Rank_Mat(int , int);

void swap(int, int, int);

/* This function exchange two rows of a matrix */

void swap( int row1,int row2, int col)

{

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

{

int temp = mat[row1][i];

mat[row1][i] = mat[row2][i];

mat[row2][i] = temp;

}

}

/* This function find rank of matrix */

int Rank_Mat(int row1, int col1)

{

int r, c;

for(r = 0; r< col1; r++)

{

display(R,C);

if( mat[r][r] ) // Diagonal element is not zero

for(c = 0; c < row1; c++)

if(c != r)

{

/* Make all the elements above and below the current principal diagonal element zero */

float ratio = mat[c][r]/ mat[r][r];

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

mat[c][i] -= ratio * mat[r][i];

}

else

printf("\n");

/* Principal Diagonal elment is zero */

else

{

for(c = r+1 ; c < row1; c++)

if (mat[c][r])

{

/* Find non zero elements in the same column */

swap(r,c,col1);

break ;

}

if(c == row1)

{

-- col1;

for(c = 0; c < row1; c ++)

mat[c][r] = mat[c][col1];

}

--r;

}

}

return col1;

}

/* Output function */

void display( int row, int col)

{

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

{

for(j = 0; j < col; j++)

{

printf(" %d", mat[i][j]);

}

printf("\n");

}

}

/* Input function */

void input( int row, int col)

{

int value;

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

{

for(j = 0 ; j<col; j++)

{

printf("Input Value for: %d: %d: ", i+1, j+1);

scanf("%d", &value);

mat[i][j] = value;

}

}

}

/* main function */

void main()

{

int rank;

printf("\n Input number of rows:");

scanf("%d", &R);

printf("\n Input number of cols:");

scanf("%d", &C);

input(R, C);

printf("\n Row is : %d", R);

printf("\n Column is : %d \n", C);

printf("\n Entered Two Dimensional array is as follows:\n");

display(R,C);

printf("\n Row is : %d", R);

printf("\n Column is : %d\n", C);

rank = Rank_Mat(R, C);

printf("\n Rank of above matrix is : %d", rank);

}

GENERAL MULTIDIMENSIONAL ARRAYS

General multidimensional arrays can be defined by analogously.

Program to illustrate a 9 subscript array:

# include<stdio.h>

# define r 2

void main()

{

int m[r][r][r][r][r][r][r][r][r];

int a, b, c, d, e, f, g, h, i;

/* Input section */

for (a = 0; a < r; a++)

for (b = 0; b < r; b++)

for (c = 0; c < r; c++)

for (d = 0; d < r; d++)

for (e = 0; e < r; e++)

for (f = 0; f < r; f++)

for (g = 0; g < r; g++)

for (h = 0; h < r; h++)

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

m[a][b][c][d][e][f][g][h][i] = a+b+c+d+e+f+g+h+i;

/* Output section row major order */

printf("\n ADDRESS ARRAY M WITH INDEX VALUE \n");

for (a = 0; a < r; a++)

for (b = 0; b < r; b++)

for (c = 0; c < r; c++)

for (d = 0; d < r; d++)

for (e = 0; e < r; e++)

for (f = 0; f < r; f++)

for (g = 0; g < r; g++)

for (h = 0; h < r; h++)

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

{

printf("\n 0x%x", &m[a][b][c][d][e][f][g][h][i]);

printf(" m[%d][%d][%d][%d][%d][%d][%d][%d][%d] = %d",a,

b, c, d, e, f, g, h, i, m[a][b][c][d][e][f][g][h][i]);

}

/* Column major order */

printf("\n ADDRESS ARRAY M WITH INDEX VALUE \n");

\

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

for (h = 0; h < r; h++)

for (g = 0; g < r; g++)

for (f = 0; f < r; f++)

for (e = 0; e < r; e++)

for (d = 0; d < r; d++)

for (c = 0; c < r; c++)

for (b = 0; b < r; b++)

for (a = 0; a < r; a++)

{

printf("\n 0x%x", &m[a][b][c][d][e][f][g][h][i]);

printf(" m[%d][%d][%d][%d][%d][%d][%d][%d][%d] = %d",a, b, c, d, e, f, g, h, i, m[a][b][c]

[d][e][f][g][h][i]);

}

}

LINKED LIST

In this section we will discuss linear data structures linked list. The computers are used in data

processing to perform operations like:

Deletion of_ information

Insertion of information_

Updating_ information

Report writing etc._

If we use fixed length memory storage (arrays) it is not always possible to perform above tasks. A

linked list allocation storage method can result in efficient use of computer memory and computer

time. Linked list are useful because:

Unpredictable storage requirements: The exact amount of data storage space required by a

program in these areas often depends on the data begin processed and consequently this

requirement can not be easily determined at the time of writing the program.

Extensive manipulation of the stored data: Program in these areas requires the operations such as

insertion and deletion to perform frequent operations on the data.

A linked list is defined as a collection of nodes. Each node has two parts:

Information

TREES

INTRODUCTION

A tree structure means that the data is organized as branches, which relate the information, one

field where such structure is commonly used in the investigation of genealogies.

LINEAGE CHART

The lineage chart represents ancestors and in this example Mc dowel has two children Scot and

Leacha. Don and Mac are children of Scot and Scot is son of Mc dowel thus we can say that Mc

dowel is the grand father of Don and Mac. Thus as we go further we find that this lineage chart is

useful is the investigation of family history called genealogies.

A tree T is defined as a finite set of one or more nodes such that

There is a special node called the root R._

0 disjoint sets T1, T2, .Tn, The remaining nodes are divided into n _ Where each of

these

sets is a tree. T1, T2, .Tn is called the sub-tree of the root.

In other words one may define a tree as a collection of nodes and each node is linked with another

node with the help of a branch. The nodes are connected in such a way that there are no loops and

there is a special node called root.

Each node in a tree is assigned a level number as follows The root node R of the tree is assigned

a level number 0, and a node is assigned a level number, which is one more than the level number

of its parent(Root) of the sub-tree to which it belongs. The nodes, which are at the same level

numbers, are said to be of the same generation. The height or depth of a tree is the maximum

number of nodes in a branch. This turns out to be one more than the largest level number of the

tree.

BINARY TREE

A binary tree is an important type of data structure, which is very useful. A tree is binary tree if

each node of it have at most two branches . In other words we can say that if every node of a tree

can have at most degree two, then this is called a binary tree. In a binary tree left and right sub-

trees distinguish sub-trees of a node.

A binary tree T is a finite set of nodes, which is either empty or consists of special node called root

R and two disjoint binary trees T1 and T2 (which are called the left sub-tree and right sub-trees,

respectively). If T1 is non-empty then the root of T1 is called the left successor of R. If T2 is non-

empty then the root of T2 is known as right successor of R.

Binary tree --- T

Left sub-tree of the Binary tree T

Right sub-tree of the binary tree T

Algorithm to create Binary tree

/* Program To Create Binary TREE */

# include<stdio.h>

# include<malloc.h>

struct NODE

{

int Info;

struct NODE *Left_Child;

struct NODE *Right_Child;

};

struct NODE *Binary_Tree (char *, int, int);

void Output(struct NODE *, int );

/* Function to insert an element into tree */

struct NODE * Binary_Tree (char *List, int Lower, int Upper)

{

struct NODE *Node;

int Mid = (Lower + Upper)/2;

Node = (struct NODE *) malloc(sizeof(struct NODE));

Node->Info = List [Mid];

if ( Lower>= Upper)

{

Node->Left_Child = NULL;

Node->Right_Child = NULL;

return (Node);

}

if (Lower <= Mid - 1)

Node->Left_Child = Binary_Tree (List, Lower, Mid - 1);

else

Node->Left_Child = NULL;

if (Mid + 1 <= Upper)

Node->Right_Child = Binary_Tree (List, Mid + 1, Upper);

else

Node->Right_Child = NULL;

return(Node);

}

/* Output function */

void Output(struct NODE *T, int Level)

{

int i;

if (T)

{

Output(T->Right_Child, Level+1);

printf("\n");

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

printf(" ");

printf("%c", T->Info);

Output(T->Left_Child, Level+1);

}

}

/* Function main */

void main()

{

char List[100];

int Number = 0;

char Info ;

char choice;

struct NODE *T = (struct NODE *) malloc(sizeof(struct

NODE));

T = NULL;

printf("\n Input choice 'b' to break:");

choice = getchar();

while(choice != 'b')

{

printf("\n Input information of the node: ");

scanf("%c", &Info);

List[Number++] = Info;

fflush(stdin);

printf("\n Input choice 'b' to break:");

choice = getchar();

}

Number --;

printf("\n Number of elements in the lsit is %d", Number);

T = Binary_Tree(List, 0, Number);

Output(T,1);

}

COMPLETE BINARY TREE

A binary tree T is called complete if each node of t can have at most two children. A binary tree T

at level L can have at most 2L nodes. For example:

If L = 0, then 20 = 1 implies that there is only one node in the tree that is a root.

If L = 1, then 21 = 2 implies that there are only two nodes in the tree at level 1 a left and right

successor of root.

If L = 2, then 22 = 4 implies that there are only four nodes in the tree at level 2 and so on.

Complete Binary Tree

If we assume that v1 = 1 is a root and its left sub-trees root is v2 = 2*v1 = 2*1 = 2 and right

sub-trees root is v3 = 2*v1 + 1 = 2*1 + 1 = 3 and we consider the 4th nodes its value is 4 then

its left sub-tree value is = 4*2 = 8, and right sub-trees value is 4*2 + 1 = 9 and so on. If we

consider node v then its left child will be at position 2*v and right will be at position 2*v + 1.

Thus the depth of the binary tree with n nodes is given by

Dn =[ Log 2 n+1]

/* Finding Depth of Binary Tree */

/* DEPTH_BT.C */

# include<stdio.h>

# include<malloc.h>

struct NODE

{

char Info;

struct NODE *Left_Child;

struct NODE *Right_Child;

};

int depth = 0;

void Output (struct NODE *, int );

int Depth (struct NODE *, int );

struct NODE *Create_Tree (char , struct NODE *);

/* Output function */

void Output(struct NODE *T, int Level)

{

int i;

if (T)

{

Output(T->Right_Child, Level+1);

printf("\n");

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

printf(" ");

printf("%c", T->Info);

Output(T->Left_Child, Level+1);

}

}

/* Find depth of the tree */

int Depth (struct NODE *Node, int Level)

{

if (Node != NULL)

{

if (Level > depth)

depth = Level;

Depth (Node->Left_Child, Level + 1);

Depth (Node->Right_Child, Level + 1);

}

return (depth);

}

/* Create binary tree */

struct NODE * Create_Tree (char Info, struct NODE *Node)

{

if (Node == NULL)

{

Node = (struct NODE *) malloc(sizeof(struct NODE));

Node->Info = Info;

Node->Left_Child = NULL;

Node->Right_Child = NULL;

return (Node);

}

/* Test for the left child */

if (Info < Node->Info)

Node->Left_Child = Create_Tree (Info, Node->Left_Child);

else

/* Test for the right child */

if (Info > Node->Info)

Node->Right_Child = Create_Tree (Info, Node->Right_Child);

return(Node);

}

/* Function main */

void main()

{

int Number = 0;

char Info ;

char choice;

int depth;

struct NODE *T = (struct NODE *) malloc(sizeof(struct NODE));

T = NULL;

printf("\n Input choice 'b' to break:");

choice = getchar();

while(choice != 'b')

{

fflush(stdin);

printf("\n Input information of the node: ");

scanf("%c", &Info);

T = Create_Tree(Info, T);

Number++;

fflush(stdin);

printf("\n Input choice 'b' to break:");

choice = getchar();

}

printf("\n Number of elements in the list is %d", Number);

printf("\n Tree is \n");

Output(T, 1);

depth = Depth(T, 0);

printf("\n Depth of the above tree is: %d", depth);

}

REPRESENTATION OF BINARY TREE

There are two traditional popular techniques that are used to maintain binary tree in the memory.

These are :

Sequential_ representation.

Linked list representation._

SEQUENTIAL REPRESENTATION

A sequential representation of a binary tree requires numbering of nodes; starting with nodes on

level 0, then on level 1, and so on. The node are numbered from left to right. The nodes of the

binary tree are maintained in a one-dimensional array.

Binary Tree -- T

LINKED LIST REPRESENTATION

The problem associated with the sequential representation of binary tree can be overcome through

the use of the linked list representation. In this representation each node requires three fields, one

for the link of the left child, second field for representing the information associated with the node

and the third field is used to represent the link of the right child.

Fig. Binary tree T

TRAVERSING BINARY TREE

Traversing means visiting each node exactly once. A full traversal of a binary tree T produces a

linear order of elements existing in T. There are three basic ways for traversing a binary tree.

PREORDER

In this technique first of all we process the root R of the binary tree T. Then we traverse the left

sub- tree T1 of R in preorder, which means that we traverse root of the sub- tree T1 first and then

its left sub- tree. After traversing left sub- tree of R then we take over right sub- tree of R and

process all the nodes in preorder.

Fig. (A) Binary tree T with 13 nodes

Recursive algorithm of preorder traversing

IN ORDER

In the inorder traversing technique first of all we process the left sub- tree T1 of the root R in the

inorder. Then process the root R and at the last we process the right sub-tree T2 of R.

Recursive algorithm of inorder traversing

POST ORDER

In this technique first of all, we process the left sub-tree T1 of R in postorder, then the right sub-

tree T2 in postorder and at the last the root R.

Recursive algorithm of postorder traversing

SEARCH TREE

A binary search tree is a tree that is either empty or in which each node possesses a key that

satisfies the following conditions:

(i) All keys (if any) in the left sub-tree of the root precede the key in the root.

(ii) The key in the root precedes all keys (if any) in its right sub-tree.

(iii) The left and right sub-trees of the root are again search trees.

Binary search algorithm

/* Searching Binary Tree */

/* SEARCH_B.C */

# include<stdio.h>

# include<malloc.h>

struct NODE

{

char Info;

struct NODE *Left_Child;

struct NODE *Right_Child;

};

int flag = 0;

struct NODE *Binary_Tree (char *, int, int);

void Output(struct NODE *, int );

int Search_Node(struct NODE *, char);

/* Function to create an binary tree */

struct NODE * Binary_Tree (char *List, int Lower, int Upper)

{

struct NODE *Node;

int Mid = (Lower + Upper)/2;

Node = (struct NODE*) malloc(sizeof(struct NODE));

Node->Info = List [Mid];

if ( Lower>= Upper)

{

Node->Left_Child = NULL;

Node->Right_Child = NULL;

return (Node);

}

if (Lower <= Mid - 1)

Node->Left_Child = Binary_Tree (List, Lower, Mid - 1);

else

Node->Left_Child = NULL;

if (Mid + 1 <= Upper)

Node->Right_Child = Binary_Tree (List, Mid + 1, Upper);

else

Node->Right_Child = NULL;

return(Node);

}

/* Output function */

void Output(struct NODE *T, int Level)

{

int i;

if (T)

{

Output(T->Right_Child, Level+1);

printf("\n");

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

printf(" ");

printf("%c", T->Info);

Output(T->Left_Child, Level+1);

}

}

/* Insert a node in the tree */

int Search_Node(struct NODE *Node, char Info)

{

while (Node != NULL)

{

if (Node->Info == Info)

{

flag = 1;

return(flag);

}

else

if(Info < Node->Info)

{

Node = Node->Left_Child;

}

else

{

Node = Node->Right_Child;

}

}

return(flag);

}

/* Function main */

void main()

{

int flag;

char List[100];

int Number = 0;

char Info ;

char choice;

struct NODE *T = (struct NODE *) malloc(sizeof(struct NODE));

T = NULL;

printf("\n Input choice 'b' to break:");

choice = getchar();

while(choice != 'b')

{

fflush(stdin);

printf("\n Input information of the node: ");

scanf("%c", &Info);

List[Number++] = Info;

fflush(stdin);

printf("\n Input choice 'b' to break:");

choice = getchar();

}

Number --;

printf("\n Number of elements in the list is %d", Number+1);

T = Binary_Tree(List, 0, Number);

printf("\n Tree is \n");

Output(T, 1);

fflush(stdin);

printf("\n Input the information of the node to which want to search: ");

scanf("%c", &Info);

flag = Search_Node(T, Info);

if (flag)

{

printf("\n Search is successful \n");

}

else

printf("Search unsuccessful");

}

DELETION IN A BINARY TREE

The deletion is an easy task if the deleted node has only one sub-tree. In this case we simply link

the parent of the deleted node to its sub-tree. When the element to be deleted has both left and

right sub-trees nonempty, the problem becomes more complicate.

Deletion in binary search tree phase 1

Deletion in binary search tree phase 2

Deletion in Binary search tree

/* Deleting in Binary Tree */

# include<stdio.h>

# include<malloc.h>

struct NODE

{

int Info;

struct NODE *Left_Child;

struct NODE *Right_Child;

};

int depth;

void Output (struct NODE *, int );

struct NODE *Delet_Node (struct NODE *, int );

struct NODE *Create_Tree (int , struct NODE *);

struct NODE * DELE(struct NODE *, struct NODE *);

/* Output function */

void Output(struct NODE *T, int Level)

{

int i;

if (T)

{

Output(T->Right_Child, Level+1);

printf("\n");

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

printf(" ");

printf("%c", T->Info);

Output(T->Left_Child, Level+1);

}

}

/* Delete a node in the binary tree */

struct NODE * DELE(struct NODE *Node1, struct NODE *Node)

{

struct NODE *DNode;

if (Node1->Right_Child != NULL)

Node1->Right_Child = DELE(Node1->Right_Child, Node);

else

{

DNode = Node1;

Node->Info = Node1->Info;

Node1 = Node1->Left_Child;

free(DNode);

}

return (Node1);

}

/* Deletion in binary tree */

struct NODE * Delet_Node (struct NODE *Node, int Info)

{

struct NODE *Temp;

if (Node == NULL)

{

printf("\n Information does not exist in the above tree");

return (Node);

}

else

{

if (Info < Node->Info )

Node->Left_Child = Delet_Node (Node->Left_Child, Info);

else

if (Info > Node->Info )

Node->Left_Child = Delet_Node (Node->Right_Child, Info);

else

{

Temp = Node;

if (Temp->Right_Child == NULL)

{

Node = Temp->Left_Child;

free(Temp);

}

else

if (Temp->Left_Child == NULL)

{

Node = Temp->Right_Child;

free(Temp);

}

else

Temp->Left_Child = DELE(Temp->Left_Child, Temp);

}

}

return(Node);

}

/* Create binary tree */

struct NODE * Create_Tree (int Info, struct NODE *Node)

{

if (Node == NULL)

{

Node = (struct NODE *) malloc(sizeof(struct NODE));

Node->Info = Info;

Node->Left_Child = NULL;

Node->Right_Child = NULL;

return (Node);

}

/* Test for the left child */

if (Info < Node->Info)

Node->Left_Child = Create_Tree (Info, Node->Left_Child);

else

/* Test for the right child */

if (Info >= Node->Info)

Node->Right_Child = Create_Tree (Info, Node->Right_Child);

return(Node);

}

/* Function main */

void main()

{

int Number = 0;

int Info ;

char choice;

int depth;

struct NODE *T = (struct NODE *) malloc(sizeof(struct NODE));

T = NULL;

printf("\n Input choice 'b' to break:");

choice = getchar();

while(choice != 'b')

{

fflush(stdin);

printf("\n Input information of the node: ");

scanf("%c", &Info);

T = Create_Tree(Info, T);

Number++;

fflush(stdin);

printf("\n Input choice 'b' to break:");

choice = getchar();

}

fflush(stdin);

printf("\n Number of elements in the list is %d", Number);

printf("\n Tree is \n");

Output(T, 1);

printf("\n Input the information to which want remove from the above tree: ");

scanf("%c", &Info);

T = Delet_Node(T, Info);

printf("\n Tree after deletion of a node: ");

Output(T, 1);

}

AVL TREE

A tree is called AVL tree (Balanced binary tree), if each node possesses one of the following

properties:

A node is called left heavy, if the longest path in its left sub-tree is one longer than the longest

path of its right sub-tree.

A node is called right heavy, if the longest path in its right sub-tree is one longer than the longest

path of its left sub-tree.

A node is called balanced, if the longest paths in both the right and left sub-trees are equal.

A Balanced Binary tree

Insertion Algorithm for AVL tree

/* Create AVL Binary TREE */

/* AVL_TREE.C */

# include<stdio.h>

# include<malloc.h>

# define F 0

# define T 1

struct NODE

{

char Info;

int Flag;

struct NODE *Left_Child;

struct NODE *Right_Child;

};

struct NODE *Binary_Tree (char , struct NODE *, int *);

void Output(struct NODE *, int );

struct NODE *Balance_Right_Heavy(struct NODE *, int *);

struct NODE *Balance_Left_Heavy(struct NODE *, int *);

struct NODE *DELETE(struct NODE *, struct NODE *, int *);

struct NODE *Delete_Element(struct NODE *, char , int *);

/* Function to insert an element into tree */

struct NODE * Binary_Tree (char Info, struct NODE *Parent, int *H)

{

struct NODE *Node1;

struct NODE *Node2;

if(!Parent)

{

Parent = (struct NODE *) malloc(sizeof(struct NODE));

Parent->Info = Info;

Parent->Left_Child = NULL;

Parent->Right_Child = NULL;

Parent->Flag = 0;

*H = T;

return (Parent);

}

if(Info < Parent->Info)

{

Parent->Left_Child = Binary_Tree(Info, Parent->Left_Child, H);

if(*H)

/* Left branch has grown higher */

{

switch(Parent->Flag)

{

case 1: /* Right heavy */

Parent->Flag = 0;

*H = F;

break;

case 0: /* Balanced tree */

Parent->Flag = -1;

break;

case -1: /* Left heavy */

Node1 = Parent->Left_Child;

if(Node1->Flag == -1)

{

printf("\n Left to Left Rotation\n");

Parent->Left_Child= Node1->Right_Child;

Node1->Right_Child = Parent;

Parent->Flag = 0;

Parent = Node1;

}

else

{

printf("\n Left to right rotation\n");

Node2 = Node1->Right_Child;

Node1->Right_Child = Node2->Left_Child;

Node2->Left_Child = Node1;

Parent->Left_Child = Node2->Right_Child;

Node2->Right_Child = Parent;

if(Node2->Flag == -1)

Parent->Flag = 1;

else

Parent->Flag = 0;

if(Node2->Flag == 1)

Node1->Flag = -1;

else

Node1->Flag = 0;

Parent = Node2;

}

Parent->Flag = 0;

*H = F;

}

}

}

if(Info > Parent->Info)

{

Parent->Right_Child = Binary_Tree(Info, Parent->Right_Child, H);

if(*H)

/* Right branch has grown higher */

{

switch(Parent->Flag)

{

case -1: /* Left heavy */

Parent->Flag = 0;

*H = F;

break;

case 0: /* Balanced tree */

Parent->Flag = 1;

break;

case 1: /* Right heavy */

Node1 = Parent->Right_Child;

if(Node1->Flag == 1)

{

printf("\n Right to Right Rotation\n");

Parent->Right_Child= Node1->Left_Child;

Node1->Left_Child = Parent;

Parent->Flag = 0;

Parent = Node1;

}

else

{

printf("\n Right to Left Rotation\n");

Node2 = Node1->Left_Child;

Node1->Left_Child = Node2->Right_Child;

Node2->Right_Child = Node1;

Parent->Right_Child = Node2->Left_Child;

Node2->Left_Child = Parent;

if(Node2->Flag == 1)

Parent->Flag = -1;

else

Parent->Flag = 0;

if(Node2->Flag == -1)

Node1->Flag = 1;

else

Node1->Flag = 0;

Parent = Node2;

}

Parent->Flag = 0;

*H = F;

}

}

}

return(Parent);

}

/* Output function */

void Output(struct NODE *Tree,int Level)

{

int i;

if (Tree)

{

Output(Tree->Right_Child, Level+1);

printf("\n");

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

printf(" ");

printf("%c", Tree->Info);

Output(Tree->Left_Child, Level+1);

}

}

/* Balancing Right Heavy */

struct NODE * Balance_Right_Heavy(struct NODE *Parent, int *H)

{

struct NODE *Node1, *Node2;

switch(Parent->Flag)

{

case -1:

Parent->Flag = 0;

break;

case 0:

Parent->Flag = 1;

*H= F;

break;

case 1: /* Rebalance */

Node1 = Parent->Right_Child;

if(Node1->Flag >= 0)

{

printf("\n Right to Right Rotation\n");

Parent->Right_Child= Node1->Left_Child;

Node1->Left_Child = Parent;

if(Node1->Flag == 0)

{

Parent->Flag = 1;

Node1->Flag = -1;

*H = F;

}

else

{

Parent->Flag = Node1->Flag = 0;

}

Parent = Node1;

}

else

{

printf("\n Right to Left Rotation\n");

Node2 = Node1->Left_Child;

Node1->Left_Child = Node2->Right_Child;

Node2->Right_Child = Node1;

Parent->Right_Child = Node2->Left_Child;

Node2->Left_Child = Parent;

if(Node2->Flag == 1)

Parent->Flag = -1;

else

Parent->Flag = 0;

if(Node2->Flag == -1)

Node1->Flag = 1;

else

Node1->Flag = 0;

Parent = Node2;

Node2->Flag = 0;

}

}

return(Parent);

}

/* Balancing Left Heavy */

struct NODE * Balance_Left_Heavy(struct NODE *Parent, int *H)

{

struct NODE *Node1, *Node2;

switch(Parent->Flag)

{

case 1:

Parent->Flag = 0;

break;

case 0:

Parent->Flag = -1;

*H= F;

break;

case -1: /* Rebalance */

Node1 = Parent->Left_Child;

if(Node1->Flag <= 0)

{

printf("\n Left to Left Rotation\n");

Parent->Left_Child= Node1->Right_Child;

Node1->Right_Child = Parent;

if(Node1->Flag == 0)

{

Parent->Flag = -1;

Node1->Flag = 1;

*H = F;

}

else

{

Parent->Flag = Node1->Flag = 0;

}

Parent = Node1;

}

else

{

printf("\n Left to Right Rotation\n");

Node2 = Node1->Right_Child;

Node1->Right_Child = Node2->Left_Child;

Node2->Left_Child = Node1;

Parent->Left_Child = Node2->Right_Child;

Node2->Right_Child = Parent;

if(Node2->Flag == -1)

Parent->Flag = 1;

else

Parent->Flag = 0;

if(Node2->Flag == 1)

Node1->Flag = -1;

else

Node1->Flag = 0;

Parent = Node2;

Node2->Flag = 0;

}

}

return(Parent);

}

/* Replace the node at which key is found with last right key of a left child */

struct NODE * DELETE(struct NODE *R, struct NODE *Temp, int *H)

{

struct NODE *Dnode = R;

if( R->Right_Child != NULL)

{

R->Right_Child = DELETE(R->Right_Child, Temp, H);

if(*H)

R = Balance_Left_Heavy(R, H);

}

else

{

Dnode = R;

Temp->Info = R->Info;

R = R->Left_Child;

free(Dnode);

*H = T;

}

return(R);

}

/* Delete the key element from the tree */

struct NODE * Delete_Element(struct NODE *Parent, char Info, int *H)

{

struct NODE *Temp;

if(!Parent)

{

printf("\n Information does not exist");

return(Parent);

}

else

{

if (Info < Parent->Info )

{

Parent->Left_Child = Delete_Element(Parent->Left_Child,

Info, H);

if(*H)

Parent = Balance_Right_Heavy(Parent, H);

}

else

if(Info > Parent->Info)

{

Parent->Right_Child = Delete_Element(Parent-> Right_Child,

Info, H);

if(*H)

Parent = Balance_Left_Heavy(Parent, H);

}

else

{

Temp= Parent;

if(Temp->Right_Child == NULL)

{

Parent = Temp->Left_Child;

*H = T;

free(Temp);

}

else

if(Temp->Left_Child == NULL)

{

Parent = Temp->Right_Child;

*H = T;

free(Temp);

}

else

{

Temp->Left_Child = DELETE(Temp->Left_Child, Temp, H);

if(*H)

Parent = Balance_Right_Heavy(Parent, H);

}

}

}

return(Parent);

}

/* Function main */

void main()

{

int H;

char Info ;

char choice;

struct NODE *Tree = (struct NODE *)malloc(sizeof(struct NODE));

Tree = NULL;

printf("\n Input choice 'b' to break:");

choice = getchar();

while(choice != 'b')

{

fflush(stdin);

printf("\n Input information of the node: ");

scanf("%c", &Info);

Tree = Binary_Tree(Info, Tree, &H);

printf("\n Tree is:\n");

Output(Tree, 1);

fflush(stdin);

printf("\n Input choice 'b' to break:");

choice = getchar();

}

fflush(stdin);

while(1)

{

printf("\n Input choice 'b' to break:");

printf("\n Input the key value want to deletedir:");

scanf("%c", &Info);

if (Info == 'b')

break;

Tree = Delete_Element(Tree, Info, &H);

printf("\n Tree is:\n");

Output(Tree, 1);

}

}

HEAP SORT

A heap is an ordered balanced binary tree in which the value of the node at the root of any sub-

tree is less than or equal to the value of either of its children. This inherent ordering implies that

only valued items may be placed in the heap. In general a heap represents a table of n elements or

records satisfying the following property:

n and i = j Ni for 2 Nj | j/2 |

A heap satisfying above definition is called a mim-heap.

Algorithm of Heap construction

Heap sort algorithm

/*PROGRAM IMPLEMENTING HEAP SORT ALGORITHM */

# include<stdio.h>

void heap_sort(int *, int );

void create_heap(int *, int);

void display(int *, int);

/* Definition of the function */

void create_heap(int list[], int n )

{

int k, j, i, temp;

for(k = 2 ; k <= n; ++k)

{

i = k ;

temp = list[k];

j = i / 2 ;

while((i > 1) && (temp > list[j]))

{

list[i] = list[j];

i = j ;

j = i / 2 ;

if ( j < 1 )

j = 1 ;

}

list[i] = temp ;

}

}

/* End of heap creation function */

/* Definition of the function */

void heap_sort(int list[], int n)

{

int k, temp, value, j, i, p;

int step = 1;

for(k = n ; k >= 2; --k)

{

temp = list[1] ;

list[1] = list[k];

list[k] = temp ;

i = 1 ;

value = list[1];

j = 2 ;

if((j+1) < k)

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

j ++;

while((j <= ( k-1)) && (list[j] > value))

{

list[i] = list[j];

i = j ;

j = 2*i ;

if((j+1) < k)

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

j++;

else

if( j > n)

j = n ;

list[i] = value;

} /* end of while statement */

printf("\n Step = %d ", step);

step++;

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

printf(" %d", list[p]);

} /* end for loop */

}

/* Display function */

void display(int list[], int n)

{

int i;

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

{

printf(" %d", list[i]);

}

}

/* Function main */

void main()

{

int list[100];

int i, size = 13 ;

printf("\n Size of the list: %d", size);

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

{

list[i] = rand() % 100;

}

printf("\n Entered list is as follows:\n");

display(list, size);

create_heap(list, size);

printf("\n Heap\n");

display(list, size);

printf("\n\n");

heap_sort(list,size);

printf("\n\n Sorted list is as follows :\n\n");

display(list,size);

}

GRAPHS

BASIC CONCEPTS AND DEFINITIONS

A Graph G is defined as a set of two tuples that is G=(V, E), where V represents set of vertices of G

and E represents the set of edges of G.

E1

E2 E3

E7 E8 E9

E4

E4 E5

GRAPH G

The figure above represents a Graph. Now here in Graph G =(V, E), an edge that is directed from

one vertex to another is called directed edge, while an edge which has no specific direction is called

an undirected edge. A graph in which every edge is directed is called a directed graph or a digraph.

A graph in which every edge is undirected is called undirected graph. If some edges in a graph are

directed and some edges are undirected then the graph is called mixed graph.

E be a"Let G = (V, E) be a graph and e directed edge associated with ordered pair of vertices (v1,

v2). Then the edge e is said to be initiating from the vertex v1 and terminating at the vertex v2.

Thus vertex v1 and v2 are also called the initial and terminal vertices of edge E, which joins the

vertices v1 and v2 in graph G. It is an incident to the"e, e vertices v1 and v2. An edge of a graph

that joins a vertex to it is called sling. The direction of the loop is of no significance; hence it can be

considered either a directed or undirected edge.

When in a graph, two or more than two edges are used to join two vertices, such edges are called

parallel edges and the graph is called parallel edges and the graph is called multi-graph.

There are three parallel edges between the vertices 1 and 4 and three parallel edges between

vertices 5 and 6. If there is only one edge between a pair of vertices in a graph then such a graph

is called simple graph. Fig 4.1 represents a simple graph. A graph with edge value is called

weighted graph.

Fig 4.3 5

6 3 4 1

2

WEIGHTED GRAPH

In a graph a vertex, which is not adjacent to any other vertices in the graph, is called an isolated

vertex. A graph containing only isolated vertices is called null graph or in other words a graph

without an edge is called a null graph.

In a directed graph for any vertex v the number of edges which have vertex v as their initial vertex

is called the out-degree of v. The number of edges, which have v as their terminal vertex, is called

the in-degree of v. The sum of out-degree and in-degree of a vertex is called the total degree of

the vertex. In case of undirected graph, the degree of a vertex is the number of edges incident on

it. The total degree of a loop is 2 and degree of an isolated vertex is 0.

A sequence of edges of a digraph such that the terminal vertex of an edge sequence in the initial

vertex of the next edge if exists is called the path.

REPRESENTATION OF GRAPH

There are two popular ways that are used to maintain a graph in a computer memory. These are :

1 Sequential

2 Linked list

SEQUENTIAL REPRESENTATION

The graphs can be represented as matrices in sequential representation. There are two most

common matrices. These are:

1 Adjacency

2 Incidence

The adjacency matrix is a sequence matrix with one row and one column for each vertex. The

values of the matrix are either 0 or 1. A value of 1 for row i and column j implies that edge eij

exists between vi and vj vertices. A value of 0 implies that there is no edge between vertex vi and

vj . In other words we can say that if graph G consists of v1,v2,v3,..vn vertices then the

adjacency matrix A = [aij] of the graph G is the n x n matrix and can be defined as :

1 If vi is adjacent to vj (that is if there is an edge between vi and vj)

aij = 0 If there is no edge between vi and vj

Such a matrix A, which contains entries of only 0 and 1, is called a bit matrix or a Boolean matrix.

The adjacency matrix A of the graph G does depend on the ordering of the nudes of G; that is, a

different ordering of nodes may result in different adjacency matrix. However the matrices

resulting from two different orderings are closely related in that one can be obtained from the other

by simply interchanging rows and columns. Suppose G is an undirected graph. Then the adjacency

matrix A of G will be a symmetric matrix, i.e., one in which aij = aji for every i and j. This follows

from the fact that each undirected edge [u, v] corresponds to the two directed edges (u, v) and (v,

u). The above matrix representation of a graph may be extended to multigraphs. Specifically, if G

is a multigraph, then the adjacency matrix of G is the m x m matrix A = (aij) defined by setting aij

equal to the number of edges from vi to vj.

v1 v2

v3 v4

Adjacency matrix for above graph

0 1 1 0

1 0 1 1

1 1 0 1

0 1 1 0

The incidence matrix consists of a row for every vertex and a column for every edge. The values of

the matrix are -1, 0 or 1. If the kth edge is (vi , vj), the kth column has a value 1 in the ith row, -1

in the jth row and 0 elsewhere.

PATH MATRIX

Let G be a simple directed graph with m nodes, v1, v2, v3, . . . . , vm. The path matrix or

reachability matrix of G is the m-square matrix P = (pij) defined as follows :

1 if there is a path from vi and vj

Pij = 0 otherwise

Suppose there is a path from vi to vj. vj , or there must be a-Then there must be a simple path

from vi to vj when vi cycle from vi to vj when vi = vj. Since G has only m nodes, such a simple

path must have length m - 1 or less, or such a cycle must have length m or less.

SHORTEST PATH ALGORITHM

DIJKSTRAS TECHNIQUES

This technique is used to determine the shortest path between two arbitrary vertices in a graph.

Let, weight w(vi, vj) is associated with every edge(vi, vj) in a given graph G. Furthermore, the

weights are such that the total weight from vertex vi to the vertex vk via vertex vj is w(vi, vj) +

w(vj, vk). Using this technique, the weight from a vertex vs (starting of a path) to the vertex vt

(the end of the path) in a graph G for a given path (vs, v1) , (v1, v2) , (v2, v3) ,. . . , (vi, vt) is

given by w(vs, v1) + w(v1, v2) + w(v2, v3) + . . . . w(vi, vt) . In a graph there are many possible

paths between vs and vt .

Dijkatras technique is based on assigning labels to each vertex. The label is equal to the distance

(weight) from the starting vertex to that vertex. Obviously, the starting vertex vs has a label 0. A

label can be in one of two states - temporary or permanent. A permanent label that lies along the

shortest path while a temporary label is one that has uncertainty as to whether the label is the

shortest path.

Dijkstras technique gradually changes the temporary labels to permanent labels until the end

vertex has a permanent label. At each step, the aim is to make the temporary labels shorter by

finding paths to the associated vertices using the shortest paths to the permanent labeled vertices.

After this the temporary label with the smallest value is made permanent. This process eliminates

one temporary vertex at each step, ensuring that the shortest path from vs to vt will eventually be

found.

Dijkstras Algorithm

to all vertices_Step 1: Assign a temporary label l(vi) = except vs.

Step 2: [Mark vs as permanent by assigning 0 label to it ]

l(vi) = 0

Step 3: [ Assign value of vs to vr where vr is last vertex to be made permanent ]

vr = vs

Step 4: if l(vi) > l(vk) + w(vk, vi)

l(vi) = l(vk) + w(vk, vi)

Step 5: vr = vi

Step 6: If vt has tempory label, repeat step 4 to step 5 otherwise the value of vt is permanent

label and is equal to the shortest path vs to vt.

Step 7: Exit

Example : Find the shortest path between vertex vs to vt .

vs 4 vt

5 1

2

7

v2 v3

3

Weight matrix of above graph is :

vs v2 v3 vt

vs 0 5 0 4

W = v2 7 0 0 2

v3 0 3 0 0

vt 0 0 1 0

If we replace the elements, which have 0 with 9999(very large value) except diagonal elements,

we get a distance matrix D.

vs v2 v3 vt

vs 0 5 9999 4

D = v2 7 0 9999 2

v3 9999 3 0 9999

vt 9999 9999 1 0

Now we have to travel from vs to vt in the above graph. There are two possible route

(a) from vs to vt (direct),

(b) from vertex vs to v2 and then from v2 to vt.

The distance from to possible routes are 4 and 7 represented.

Step 1, Step 2 and Step 3: Assign labels as follows and set vr = vs = v1.

vs v2 v3 vt

label: 0 9999 9999 9999

permanent: Y N N N

Step 4 and Step 5: Redefine temporary labels as follows:

Label(v2) = min(9999, 0 + 5 ) = 5

Label(v3) = min(9999,0+9999)=9999

Label(vt) = min(9999,0 + 4) = 4

Make Label(v2) permanent, vr=v2

vs v2 v3 vt

Label: 0 5 9999 9999

Permanent: Y Y N N

Step 6: Repeat Step 4 and Step 5, redefine the temporary labels as follows:

Label (v3) = min(9999,7 + 0)=7

Label (vt) = min(4,7+2) =4

Make Label(v3) permanent, vr = v3

Vs v2 v3 vt

Label: 0 5 7 9999

Permanent: Y Y Y N

Again repeat Step 4 and Step 5, redefine

Label (vt) = min(4,0+9999)

Make Label(vt)permanent set vr = vt

vs v2 v3 vt

Label: 0 5 7 4

Permanent: Y Y Y Y

Label (vt) is permanent. The shortest path length is 4.

The program to implement Dijkstras Algorithm.

/* DIJKSTRA METHOD */

# include<stdio.h>

#define size 20

#define p 1

#define t 0

#define infinity 9999

struct label

{

int predecessor;

int length;

int flag;

};

int k,min,count;

struct label state[size];

int visit_path[size];

int Short_path(int a[size][size], int , int , int ,int path[size], int *);

void Input(int , int a[size][size]);

void Output(int , int a[size][size]);

/* Shortest path computing function */

int Short_path(int a[size][size], int n, int s, int t, int path[size] , int *dist)

{

int i;

int t1,t2;

*dist = 0;

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

{

state[i].predecessor = 0;

state[i].length = infinity;

state[i].flag = T;

}

/* Make source vertex permanent */

state[s].predecessor = 0;

state[s].length = 0;

state[s].flag = P;

/* Start from source vertex */

k = s;

do

{

// Check all the paths from kth vertex and find their distance from k vertex

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

{

if(( a[k][i]> 0) && (state[i].flag ==T))

{

if((state[k].length + a[k][i]) < (state[i].length))

{

state[i].predecessor = k;

state[i].length = state[k].length + a[k][i];

}

}

}

min = infinity;

k = i;

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

{

if((state[i].flag ==T) && (state[i].length < min))

{

min = state[i].length;

k = i;

}

}

if( k == 0)

return (0);

state[k].flag = p;

}while(k != t);

/* Store optimal path */

k = t;

count = 1;

do

{

visit_path[count] = k;

count ++;

k = state[k].predecessor;

}while(k != 0);

// Reverse the vertices since algorithm stores path in reverse direction

count --;

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

{

path[i] = visit_path[count - i + 1 ];

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

{

t1 = path[i];

t2 = path[i + 1];

*dist += a[t1][t2];

}

return (count);

}

/* Input function */

void Input(int n, int a[size][size])

{

int i,j;

printf(\n Input adjacency matrix \n);

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

{

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

{

scanf(%d,&a[i][j]);

}

printf(\n);

}

}

/* Output function */

void Output(int n , int a[size][size])

{

int i,j;

printf(\n Adjacency matrix \n);

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

{

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

{

printf( %d,a[i][j]);

}

printf(\n);

}

}

/* Function main */

void main()

{

int a[size][size];

int path[size];

int org, dest, dist;

int count, i, n;

printf(\n Input the number of vertices in the graph : );

scanf(%d, &n);

Input(n,a);

Output(n, a);

printf(\n Input starting vertex : );

scanf(%d,&org);

printf(\n Input destination : );

scanf(%d,&dest);

count = Short_path(a, n, org , dest , path, &dist);

if(dist)

{

printf(\n Shortest path : %d,path[i]);

for(i =2; i<= count; i ++)

printf ( => %d,path[i]);

printf(\n Minimum distance = %i, dist);

}

else

printf( \n Path does not exise \n);

}

ADJACENCY LIST

Let G = (V, E) is a graph with n vertices. This graph can be represented by n x n adjacency matrix.

The n linked lists represent the n rows of the adjacency matrix A and there is one linked list for

each vertex in G. The vertices in the list L represent the vertices that are adjacent to the vertex L,

each vertex represented by two fields: Vertex and Link. The Vertex fields contain the indices of the

vertices adjacent to the vertex L. The adjacency matrix for G is as follows :

v1 v2 v3 v4 v5 v6

v1 0 1 0 0 1 0

v2 0 0 1 1 1 0

v3 0 0 0 0 1 0

A = v4 1 0 1 0 0 1

v5 0 0 0 0 0 0

v6 0 1 0 0 1 0

Directed Graph

Adjacency lists for the graph G

The number of distinct vj in the graph with n vertices is n(n - 1)/2.-unordered pairs(vi, vj) with vi

This is the maximum number of edges in any n vertex undirected graph. An n vertex undirected

graph with exactly n(n - 1)/2 edges is said to be complete. In the case of a directed graph having n

vertices the maximum number of edges is n(n -1).

OPERATIONS ON GRAPHS

Suppose a graph G is maintained in memory by linked representation.

GRAPH(NODE, NEXT, ADJ, START, AVAILN, DEST, LINK, AVAILE)

Searching in a Graph

Suppose we want to find the location LOC of a node N in a Graph G. The procedure for this is:

Inserting in a Graph Suppose a node is to be inserted in the graph.

Deleting a node from the graph Suppose a node is to be deleted from the graph.

GRAPH TRAVERSAL

Some times it is required to examine all the vertices in a graph in some systematic orders, as we

have seen in the case of binary trees where we use pre order ,postorder or inorder to examine the

vertices . For examining all the vertices we start from the root for trees while in the graph we start

examination from an arbitrary vertex. There are two popular techniques for examination of the

graphs. These are:

1 Depth first search(DFS)

2 Breadth first search(BFS)

DEPTH FIRST SEARCH (DFS)

This is similar to preorder examination of an order tree. Suppose the examination has just

examined a vertex vi and let w1, w2, w3,..wk, be the vertices adjacent to vi. We next examine wi

and keep w2,w3,..wk waiting. After examining w1 we examine all the vertices to which it is

adjacent to before returning to examine w2, w3, ..wk.

A 1

3

B 2 C D E 5 6 F 4

Consider the graph illustrated above. The DFS strategy results the examination indicated by the

arrows, assuming that each edge has been assigned a value of 1. Starting at vertex A the

examination numbers all the vertices down until vertex F is reached , where all the adjacent

vertices have already been marked(examined). The DFS algorithm returns to C, which still has an

unlabeled adjacent vertex D. After vertex D and E are labeled, all vertices are numbered and the

examination is complete.

A graph is called bi-connected if there is no single vertex whose removal causes the graph break

into two or more pieces. A vertex whose removal causes the graph to become disconnected is

called a cut-vertex.

A vital communication network may bedescribed by a graph, allowing each vertex to representing a

communication line and each edge indicating the presence of an interconnection between the lines.

For a cut-vertex destruction of the line would result in a break down of communications. If the

graph is bi-connected the removal of one line(vertex) would not affect the communication, since

there will still be other links.

The DFS algorithm is illustrated below:

The result of the program segment tested on the graph G is illustrated in fig below.

The adjacency matrix A of the graph is as follows:

0 1 1 0 0 0 0 0

0 0 0 1 1 0 0 0

0 0 0 0 1 0 0 0

A = 0 0 0 0 0 0 0 1

0 0 0 0 0 1 0 1

0 0 0 0 0 0 1 0

0 0 1 0 0 0 0 0

0 0 0 0 0 1 1 0

Program to illustrate Depth First Search Algorithm

/* DEPTH FIRST SEARCH TECHNIQUE */

/* DFS.C */

# include<stdio.h>

# define size 20

# define T 1

# define F 0

struct Edge

{

int terminal;

struct Edge *next;

};

struct Vertex

{

int visit;

int vertex_no;

char info;

int path_length;

struct Edge *Edge_Ptr;

};

void Table(int , int matrix [size][size], struct Vertex vert[size]);

struct Edge *Insert_Vertex (int , struct Edge *);

void DFS ( int , int *dist, struct Vertex vert [size]);

void Input(int, int a [size][size]);

void Output(int, int a [size][size]);

struct Edge * Insert_Vertex (int vertex_no, struct Edge *first)

{

struct Edge *new1, *current;

new1 = (struct Edge *) malloc(sizeof(struct Edge));

new1->terminal = vertex_no;

new1->next = NULL;

if (!first)

return (new1);

for (current = first; current->next; current = current->next);

current->next = new1;

return (first);

}

/* Initializing entries */

void Table(int vertex_num, int matrix [size][size],

struct Vertex vert[size])

{

int i, j;

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

{

vert [i].visit = F;

vert [i].vertex_no = i+1;

vert [i].info = 'A'+ i;

vert [i].path_length = 0;

vert [i].Edge_Ptr = NULL;

}

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

for (j =0; j < vertex_num ; j++)

if (matrix [i][j] > 0)

vert [i].Edge_Ptr = Insert_Vertex (j, vert [i].Edge_Ptr);

}

/* Computing path length */

void DFS ( int index, int *dist,

struct Vertex vert [size])

{

struct Edge *Link;

vert [index].visit = T;

vert [index].path_length = *dist;

*dist += 1;

for ( Link = vert [index].Edge_Ptr; Link; Link = Link->next)

if (vert [Link->terminal].visit == F)

DFS (Link->terminal, dist, vert);

}

/* Input function to read adjacency matrix */

void Input(int number, int a [size][size])

{

int i, j;

printf("\n Input the adjacency matrix \n");

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

{

for (j=0; j < number; j ++)

{

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

}

printf("\n");

}

}

/* Output function */

void Output(int number, int a [size][size])

{

int i, j;

printf("\n Adjacency matrix \n");

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

{

for (j = 0; j < number; j ++)

{

printf(" %d", a [i][j]);

}

printf("\n");

}

}

/* Function main */

void main()

{

int i;

int number, index, dist;

int a [size][size];

struct Vertex vert [size];

struct Edge *List;

printf("\n Input the number of vertices in the graph: ");

scanf("%d", &number);

Input(number, a);

Output(number, a);

Table(number, a, vert);

printf("\n Input the starting vertex 0- %d:", number-1);

scanf("%d", &index);

dist = 0;

DFS (index, &dist, vert);

printf("\n Path length of the vertex from %c", vert[index].info);

printf("\n Vertex Length Vertex Connectivity \n ");

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

{

printf("\n %c %d ", vert[i].info, vert[i].path_length);

for (List= vert[i].Edge_Ptr; List; List = List->next)

{

printf(" ");

putchar(List->terminal+'A');

}

}

}

BREADTH FIRST SEARCH (BFS)

Breadth first search(examination) of a graph is similar to level by level examination of an ordered

tree. If the examination has just visited a vertex v, then it visits all the vertices adjacent to v by

putting the vertices adjacent to those in a waiting queue to be examined, after all vertices adjacent

to v have been visited. Consider the undirected graph G illustrated below. A breadth first

examination beginning at vertex A of the graph G would first visit A and then B and C. Next D,E,F

and G will be visited and finally H. The program segment to illustrate the BFS algorithm

/* BREADTH FIRST SEARCH TECHNIQUE */

/* BFS.C */

# include<stdio.h>

# define size 20

# define T 1

# define F 0

struct Edge

{

int terminal;

struct Edge *next;

};

struct Vertex

{

int visit;

int vertex_no;

char info;

int path_length;

struct Edge *Edge_Ptr;

};

struct Q

{

int info;

struct Q *next;

};

void Table(int , int matrix [size][size], struct Vertex vert[size]);

struct Edge *Insert_Vertex (int , struct Edge *);

void BFS ( int , struct Vertex vert [size]);

void Input(int, int mat [size][size]);

void Output(int number, int mat [size][size]);

struct Q *Insert_Queue(int vertex_no, struct Q *first);

struct Q *Delete_Queue(int *vertex_no, struct Q *first);

/* Insert vertex into connectivity list */

struct Edge * Insert_Vertex (int vertex_no, struct Edge*first) {

struct Edge *new1, *current;

new1 = (struct Edge *) malloc(sizeof(struct Edge));

new1->terminal = vertex_no;

new1->next = NULL;

if (!first)

return (new1);

for (current = first; current->next; current = current->next);

current->next = new1;

return (first);

}

/* Insert vertices into queue */

struct Q * Insert_Queue(int vertex_no, struct Q *first)

{

struct Q *new1, *current;

new1 =(struct Q *) malloc(sizeof(struct Q));

new1->info = vertex_no;

new1->next = NULL;

if (!first)

return (new1);

for (current = first; current->next; current = current->next);

current->next = new1;

return (first);

}

struct Q * Delete_Queue(int *vertex_no, struct Q *first)

{

struct Q *previous;

if (!first)

return (NULL);

*vertex_no = first->info;

previous = first;

first = first->next;

free(previous);

return (first);

}

/* Initializing entries */

void Table(int vertex_num, int matrix [size][size],

struct Vertex vert[size])

{

int i, j;

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

{

vert [i].visit = F;

vert [i].vertex_no = i+1;

vert [i].info = 'A'+ i;

vert [i].path_length = 0;

vert [i].Edge_Ptr = NULL;

}

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

for (j =0; j < vertex_num ; j++)

if (matrix [i][j] > 0 )

vert [i].Edge_Ptr = Insert_Vertex (j, vert [i].Edge_Ptr);

}

/* Computing path length */

void BFS ( int index, struct Vertex vert [size])

{

struct Q *queue = NULL;

struct Edge *Link;

vert [index].visit = T;

queue = Insert_Queue(index, queue);

while(queue)

{

queue = Delete_Queue(&index, queue);

for ( Link = vert [index].Edge_Ptr; Link; Link = Link->next)

{

if (vert [Link->terminal].visit == F)

{

vert[Link->terminal].visit = T;

vert[Link->terminal].path_length=vert[index].path_length+1;

queue = Insert_Queue(Link->terminal, queue);

}

}

}

}

/* Input function to read adjacency matrix */

void Input(int number, int mat [size][size])

{

int i, j;

printf("\n Input the adjacency matrix \n");

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

{

for (j=0; j < number; j ++)

{

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

}

printf("\n");

}

}

/* Output function to display adjacency matrix */

void Output(int number, int mat [size][size])

{

int i, j;

printf("\n Adjacency matrix \n");

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

{

for (j=0; j < number; j ++)

{

printf(" %d", mat [i][j]);

}

printf("\n");

}

}

/* Function main */

void main()

{

int i, number, index;

int mat [size][size];

struct Vertex vert [size];

struct Edge *List;

printf("\n Input the number of vertices in the graph: ");

scanf("%d", &number);

Input(number, mat);

Output(number, mat);

Table(number, mat, vert);

printf("\n Input the starting vertex 0- %d :",number-1);

scanf("%d", &index);

BFS (index, vert);

printf("\n Path length of the vertex from %c", vert[index].info);

printf("\n Vertex Length Vertex Connectivity \n ");

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

{

printf("\n %c %d ",vert[i].info, vert[i].path_length);

for (List= vert[i].Edge_Ptr; List; List = List->next)

{

printf(" ");

putchar(List->terminal+'A');

}

}

}

HASHING

The search time of each algorithm discussed so far depends on the number n of elements in the

collection S of data. This section discusses a searching technique, called hashing or hash

addressing, which is essentially independent of the number n. The terminology whish we use in our

presentation of hashing will be oriented toward file management. First of all, we assume that there

is a file F of n records with a set K of keys, which uniquely determine the records in F. Secondly,

we assume that F is maintained in memory by a table T of m memory locations and that L is the

set of memory addresses of the locations in T. For notational convenience, we assume that the

keys in K and the addresses in L are (decimal) integers. ( Analogous method will work with binary

integers or with keys which are character strings, such as names, since there are standards ways

of representing strings by integers.)

Example : Suppose a company with 68 employs assigns a 4-digit employee number to each

employee which is used as the primary key in the companys employee file. We can, infect, use the

employee number as the address of the record in memory. The search will require no comparisons

at all. Unfortunately, this technique will require space for 10,000 memory locations, whereas space

for fewer than 30 such locations would actually be used. Clearly, this tradeoff space for time is not

worth the expense.

The general idea of using the key to determine the address of a record is an excellent idea, but it

must be modified so that a great deal of space is not wasted. This modification takes the form of a

function H from the set K of keys into the set L of memory addresses. Such a function,

H : K L

Is called a Hash function or Hashing function. Unfortunately, such a function H may not yield

distinct values : it is possible that two different keys k1 and k2 will yield the same Hash address.

This situation is called Collision, and some method must be used to resolve it. Accordingly, the

topic of Hashing is divided into two parts :

(1) Hash Functions

(2) Collision Resolution

We discuss these two parts separately.

HASH FUNCTIONS

The two principal L are as follows. First ofcriteria used in selecting the Hash function H : K all,

the function H should be very easy and quick to compute. Second the function H should , as far as

possible, uniformly distribute the Hash addresses through the set L so that there are a minimum

numbers of collisions. Naturally, there is no guarantee that the second condition can be completely

fulfilled without actually knowing beforehand the keys and addresses. However , certain general

techniques do help. One technique is to chop a key k into pieces and combine the pieces in some

way to form the Hash address H (k). ( The term Hashing comes from this technique of

Chopping a key into pieces.)

We next illustrate some popular hash functions. We emphasize that the computer can easily and

quickly evaluate each of these Hash functions.

(a) Division Method : Choose a number m larger than the number n of keys in K. ( The number

m is usually chosen to be a prime number or a number without small divisors, since this frequently

minimizes the number of collisions.) The hash function H is defined by

H(k) = k( mod m) or H(k) = k(mod m) + 1

Here k(mod m) denotes the remainder when is divided by m.

The second formula is used when we want the Hash addresses to range from 1 to m rather than

from 0 to m - 1.

(b) Midsquare Method : The key k is squared. Then the hash function H is defined by

H(k) = l

Where l is obtained by deleting digits from both ends of k2. we emphasize that the same positions

of k2 must be used for all of the keys.

(c) Folding Method : The key k is partitioned into a number of parts , k1,,kr , where each

part, except possibly the last, has the same number of digits as the required address. Then the

parts are added together , ignoring the last carry. That is ,

H(k) = k1 +k2 + k3+.+kr

Where the leading - digit carries , if any, are ignored. Sometimes , for extra milling , the even -

numbered parts, k2, k4, ., are each reversed before the addition.

COLLISION RESOLUTION

Suppose we want to add a new record R with key k to our file F, but suppose the memory location

address H(k) is already occupied. This situation is called collision. This sub section discusses two

generah ways of resolving collisions. The particular procedure that one chooses depends on many

factors. One important factor is the ratio of the number n of keys in K (which is a number of

records in F) to the number m of Hash addresses in L .

= n /m, is called the load factor.-This ratio,

First we show that collisions are almost impossible to avoid. Specifically, suppose a student class

has 24 students and suppose the table has space for 365 records. One random Hash function is to

choose the students birthday as the Hash address. Although the 7% is very small, it can be shown

that there is a- = 24/365 -load factor better then fifty - fifty chance that two of the students

have the same date of birth.

The efficiency of a Hash function with a Collision Resoluton procedure is measured by the average

number of probes (key comparisons) needed to find the location of the record with a given key k.

The efficiency depends. specifically, we are interested in the following-mainly on the load factor

two quantities :

) = avg. number of probes for a successful-S( search

) = avg. number of probes for an unsuccessful search-U(

Open addressing : Linear Probing and Modifications

Suppose that a new record R with key k is to be added to the memory table T, but that the

memory location hash address H (k) = h is already fulfilled. One natural way to resolve the collision

is to assign R to the first available location following T [h]. (We assume that the table T with m

locations is circular, so that T[1] comes after T[m]. ) Accordingly with such a collision procedure ,

we will search for the record R in the table T by linearly searching the location T[h],T[h + 1],T[h +

2],..until finding R or meeting an empty location, which indicates an unsuccessful search.

The above Collision Resolution is called linear Probing. The average numbers of probes for a

successful search and for an unsuccessful search are known to be the following respective

quantities :

)2)-) = 1/2( 1+1/(1--) ) and U(-) = 1/2( 1 + 1/(1--S(

-( Here = n/m is the load factor.)

One main disadvantage of Linear probing is that records tend to cluster, that is, appear next to one

another, when the load factor is greater then 50%. Such a clustering substantially increases the

average search time for a record. Two techniques of minimize clustering are as follows :

(1) Quadratic Probing : Suppose a record R with key k has the Hash address H(k) = h. Then,

instead of searching the locations with addresses h , h + 1, h + 2,.,we linearly search the location

with addresses.

h, h +1, h+4, h+9, h+16,,h+i2 , .

If the number m of locations in the table T is a prime number , then the above sequence will access

half of the location in T .

(2) Double Hashing : Here a second hash function H is used for resolving a collision, as follows.

Suppose a record R with key k has the hash m. Then we linearly search the locations

with-addresses H(k) = h and H(k) = h addresses H, h+h, h+2h, h+3h, .

If m is a prime number, then the above sequence will access all the locations in the table T.

Remark: One major disadvantage in any type of open addressing procedure is in the

implementation of deletion. Specifically, suppose a record R is deleted from the location T[r].

Afterwards, suppose we meet T[r] while searching for another record R. This dose not necessarily

means that the search is unsuccessful. Thus, when deleting the record R, we must label the

location T[r] to indicate that it previously did contain a record. Accordingly, open addressing may

seldom be used when a file F is constantly changing.

Chaining

Chaining involves maintaining two tables in memory. First of all, as before, there is a table T in

memory which contains the records in F, except that T now has an additional field LINK which is

used so that all records in T with the same hash address h may be linked together to form a linked

list. Second, there is a hash address table LIST that contains pointers to the linked lists in T.

Suppose a new record R with key k is added to file F. We place R in the first available location in

the table T and then add R to the linked list with pointer LIST [H (k)]. If the linked lists of records

are not sorted, than R is simply inserted at the beginning of its linked list. Searching for a record or

deleting a record is nothing more than searching for node or deleting a node from a linked list.

The average number of probes, using chaining, for a successful search and for an unsuccessful

search are known to be the following approximate values:

- + - e--) - and U (- 1 + -) -S (

Here the = n/m may be greater than 1, since the number m of hash addresses-load factor in L

(not the number of location in T) maybe less then the number n of records in F.

SEARCHING AND SORTING

In this chapter we will discuss some sorting and searching techniques. First we will take searching

techniques.

LINEAR SEARCH

This is the simplest technique to find out an element in an unsorted list. Let we have an unsorted

list I, which consists of n elements and want to search the value of a particular element in the list,

as, illustrated in Fig (5.1).

In this technique the value of the key is compared with the first element of the list, if match is

found then the search is terminated. Otherwise next element from the list is fetched and compared

with the key and this process is continued till the key is found or list is completely exhausted. For

example, Fig (4.2) represents the list of elements in the memory, having 6 elements

22,33,66,05,44,89 and we want to search for key == 05. Fig (4.2), Fig (4.2a), Fig (4.2b), Fig

(4.2c) illustrates the idea.

Fig (4.3) Algorithm for Linear Search

The algorithm for linear search is given in Fig (4.3). Following program segment implements the

above discussion (lsearch.c).

/* LINEAR SEARCH */

/* 1search. c */

#include<stdio.h>

int search ;

int flag ;

int input ( int *, int , int );

void linear_search (int *,int , int );

void display ( int *,int );

/* Definition of function */

void linear-search (int 1[] , int n , int element )

{

int k ;

flag = 1 ;

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

{

if (1 [k] = element )

{

printf ( \n Search is successful \n );

printf ( \n Element : % i Found at Location : % i , element , k+1 );

flag = 0 ;

}

}

if ( flag )

printf ( \n Search is unsuccessful ) ;

}

void display ( int list [] , int n )

{

int i ;

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

{

printf ( %d , list [i] ) ;

}

}

input (int list [] , int number , int key )

{

int i ;

number = 20 ;

key = 30 ;

printf ( Number of elements in the list : %d , number ) ;

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

{

list [i] = rand ( ) % 100 ;

}

printf ( \n Element to be searched : % d , key ) ;

search = key ;

return number ;

}

void main ( )

{

int number , key , list [ 200] ;

number = input ( list , number , key ) ;

key = search ;

printf ( \n Entered list as follows : \n ) ;

display ( list , number ) ;

linear-search ( list ,number , key ) ;

printf (\n in the following list \n ) ;

display ( list , number ) ;

}

BINARY SEARCH

Binary search works for sorted lists and is a very efficient searching technique. It is used to find the

location of a given element or record in a list. Other information associated with the element can

also be fetched if required. To find the location of a file in the computer directory one can use this

searching technique. If we are on the Internet then it is not a easy task using liner search to find

out the information about some records or files. For this one prefers Binary searching techniques.

Let low represents lower limit of the list 1 , high upper and mid is average of low and high that is

middle of the lower and upper limits , it is

mid =( low + high )/2

index 0 1 2 3 4 5 6 7 8 9 10 11 12

99 11 22 40 55 60 88 80 77 66 44 33 30

Fig (4.4) List in the memory

Figure 4.5

We compared the middle element with key to be searched. If the value of middle element is

greater than key , then key will exist in lower half of the list, take high = mid 1 and find new

value of mid , i.e.,

mid =( low +high )/2

Otherwise, key will exist in upper half and take

Low =mid + 1

And mid = (low + high)/2

Fig (4.6) Algorithm for Binary Search

The following program segment implements the Binary Search Algorithm.

/* Binary.c */

#include <stdio.h>

int binary_search(int array[], int value , int size)

{

int found = 0;

int high = size 1, low = 0, mid;

mid = (high + low )/2;

printf( \n\n Looking for %d\ , value);

while(( !found) && (high >= low))

{

printf(Low %d Mid %d High %d \n ,low,mid,high);

if( value == array[mid])

found = 1;

elseif( value < array[mid])

high mid 1;

else

low = mid + 1;

mid = (high + low)/2;

}

return(( found) ? mid: -1);

}

void main(void)

{

int array[100],i;

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

array[i] = i + 20;

printf(Result of search %d\n, binary_search(array,33,100));

printf(Result of search %d\n, binary_search(array,75,100));

printf(Result of search %d\n, binary_search(array,1,100));

}

BUBBLE SORT

It is very simple sorting technique. However, this sorting technique is not efficient in comparison to

other sorting techniques. But for smaller lists this sorting technique works fine. Suppose we sort

the elements in descending order, the bubble sort loops through the elements in the list comparing

the adjacent element and moves the largest element to the top of the list.

The bubble sort algorithm is given in Fig (4.8). From this algorithm it is clear that bubble sort

places the smallest element in the proper position and selects the second element and searches for

the second smallest element .Fig (4.7), Fig (4.7a), Fig (4.7b), Fig (4.7c) illustrate the complete

operation performed on 5-element list.

From the algorithm shown in Fig ( 4.8 ) it is clear that for the pass i the inner loop performs the n-i

comparisons ( because only n-i elements are examined ) to find the smallest element. Total

number of comparisons for all the passes is :

n - 1

n - i-E(n) =

i = 0

(n 1) + (n 2) + (n 3) + ***+ 2 + 1

n( n 1) / 2

n2 / 2 + O ( n ) i.e. O ( n2 )

Following program segment illustrates the algorithm given in Fig ( 4.8 )

/* bubble.c */

# include <stdio .h>

# include < stdio .h>

void bubble_sort ( int array [] , int size )

{

int temp, i, j;

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

for ( j = 0; j < size i l; j + + )

if ( array [j] < array [j + l])

{

temp = array [j];

array [j] = array [j + l];

array [j + l] = temp;

}

}

void main ( void )

{

int values [30], i ;

printf (\n Unsorted list is as follows \n )

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

{

values [i] =rand ( ) % 100 ;

printf ( %d, values [i] ) ;

}

bubble_sort ( values, 10 ) ;

printf (\n Sorted list is as follows \n ) ;

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

printf ( % d, values [i] ) ;

}

INSERTION SORT

Suppose l is the list of n elements. The insertion sort technique scans the list l[l] to l[n], inserting

each element into its proper position in the previously sorted sub-list l[l], l[2]***l[i-l].

Step =1 -0 7 3 4 1 8 2 6 5

Step = 2 -0 3 7 4 1 8 2 6 5

Step = 3 -0 3 4 7 1 8 2 6 5

Step = 4 -0 1 3 4 7 8 2 6 5

Step = 5 -0 1 3 4 7 8 2 6 5

Step = 6 -0 1 2 3 4 7 8 6 5

Step = 7 -0 1 2 3 4 6 7 8 5

Step = 8 -0 1 2 3 4 5 6 7 8

Fig (4.9) insertion sort

Insertion_sort ( l, n )

Where l - Represents the list of elements.

n - Represents number of elements in the list.

Step 1: [Initialize]

l[0] = -0

Step 2: Repeat through Step 3 to 5 for i = 1, 2, 3, 4,***n

Step 3: (i) temp = l [i]

(ii) pointer = i l

Step 4: while ( temp < l [pointer] )

(i) l [pointer + l] = l [pointer]

(ii) pointer = pointer l

Step 5: l [pointer] = temp

Step 6: Exit

Fig (4.10) Algorithm for Insertion sort

For smaller values of n this algorithm is useful. The inner loop of the algorithm performs i-1

comparisons. Hence

n

i 1E(n) =

i=1

=> 1+2+3+4+..+n 1

=> n(n-1)/2

=> O(n2)

For average case the inner loop performs (i-l) /2 comparisons.

n

E(n) = (i-1) /2

i=1

=> ( 1+2+3+4+..+n-l ) /2

=> n(n-l) /4

=> O (n2)

Fig (4.9) illustrates the algorithm given in Fig (4.10).

The program segment INSERT.C implements the above discussion.

/* Insertion sort */

/* INSERT.C */

# include<stdio .h>

# include<stdlib.h>

int i, k;

void insertion_sort (int *, int );

void display (int*, int);

void insertion_sort (int l[], int n)

{

int pointer, temp;

l [0] = -0;

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

{

pointer = i l;

temp = l[i];

while (temp < l [pointer])

{

l [pointer + l] = l [pointer];

pointer -;

}

l [pointer + l] = temp;

printf ( Step = %d, i);

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

printf ( %d, l [k]);

printf (\n);

}

}

void display ( int l [], int n)

{

printf (\n Sorted list is as follows\n);

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

printf (%d, l [i]);

}

void main ( )

{

int number =10;

int list [100] ;

int i ;

printf (\n Number of elements in the list: %i, number) ;

printf (\n Unsorted list is as follows \n) ;

for (i = l ; i < = number ; i + +)

{

list [i] = rand ( ) % 100 ;

printf ( %d, list [i]) ;

}

printf (\n) ;

printf (\n Stepwise result is as follows \n\n ;

insertion_sort (list , number );

display (list, number) ;}

Another way of implementation of above technique is given below :

/*INSERS.C */

/* INSERTION SORT */

/* INSERS.C */

# include<stdio.h>

# include<stdlib.h>

int key;

int insertion_sort(int *);

// prototype

void display(int *, int);

/* Definition of the insertion sort function */

int insertion_sort(int list[])

{

int i = 0;

int j, k ;

printf("\nElement to be inserted Break condition is -0 : ");

scanf("%d", &key);

printf("\n Selected Element is: %d", key);

while(key != -0 ) /* -0 is break condition */

{

k = i - 1;

while((key < list[k]) && (k >= 0))

{

list[k+1] = list[k];

--k;

}

list[k+1] = key ;

printf("\n List after inserting an element ");

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

printf(" %d", list[j]);

printf("\n Element to be inserted Break condition is -0: ");

scanf("%d", &key);

printf("\n Selected Element is: %d", key);

i ++;

}

return i;

}

/* End of the insertion sort function */

/* Definition of the function */

void display(int list[], int n)

{

int j;

printf("\n Final sorted list is as follows:\n");

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

printf(" %d", list[j]);

}

/* End of the display function */

void main()

{

int list[200];

int n ;

n = insertion_sort(list);

display(list,n);

}

QUICK SORT

Quick sort treats an array as a list of elements. When sort begins it selects the lists middle

elements as the list pivot. The sort then divides the list into two sub-lists one with elements that

are less than the list pivot and second list with elements greater than or equal to the list pivot.

The sort then recursively invoke itself with both lists. Each time when the sort is invoked it further

divides the elements into smaller sub-lists.

Q-sort (array, first, last)

Represents the list of elements.Where array

Representsfirst the position of the first element in the list (Only at

the starting point, its value changes during the execution of the function).

last Represents the position of the last element in the list (only at

point the value of its changes during the execution of the function).

Step 1: [Initially]

low =first

high =last

pivot =array [ (low + high)/2 ] [Middle element of the element of the

List]

Step 2: Repeat through Step 7 while (low< high )

Step 3: Repeat Step 4 while (array [low] < pivot)

Step 4: low = low + 1

Step 5: Repeat Step 6 while (array [high] > pivot)

Step 6: high = high 1

Step 7: if ( low < high )

(i) temp = array [low]

(ii) array [low] = array [high]

(iii) array [high] = temp

(iv) low = low + 1

(v) high = high 1

Step 8: if (first < high) Q_sort ( array, first, high )

Step 9: if (low < last) Q_sort ( array, low, last )

Step 10: exit

Fig (4.12) Algorithm of Quick Sort

If partition process involves n comparisons with the pivot, with at most n/2 swaps and, hence, is If

the pivot is`O(n). The question, then is how many partitions are performed such that then array is

divided into two sub-arrays of the same size, then the situation is similar to merge sort. In this

case, the algorithm is O (n log n). However, in the worst case, each partitioning will divide the

array into parts of size 1 and n-1. Partition would then be called n times, with array sizes ranging

from 1 to n. The average case performance for quick sort algorithm is

O ( n log n ).

The following program segment implements the quick sort technique (quick.c)

/* quick.c */

#include <stdio.h>

#include <stdlib.h>

void quick_sort(int array[], int first, int last)

{

int temp, low, high, list_separator;

low = first;

high = last;

list_separator = array[(first + last) / 2];

do {

while (array[low] < list_separator)

low++;

while (array[high] > list_separator)

high--;

if (low <= high)

{

temp = array[low];

array[low++] = array[high];

array[high--] = temp;

}

} while (low <= high);

if (first < high)

quick_sort(array, first, high);

if (low < last)

quick_sort(array, low, last);

}

void main(void)

{

int values[100], i;

printf("\n Unsorted list is as follows \n");

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

{

values[i] = rand() % 100;

printf(" %d", rand() %100);

}

quick_sort(values, 0, 19);

printf("\n Sorted list as follows\n");

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

printf("%d ", values[i]);

}

SELECTION SORT

The selection sort starts from first element and searches the entire list until it finds the minimum

value. The sort places the minimum value in the first place, selects the second element and

searches for the second smallest element. The process continues until the complete list is sorted.

From the algorithm given in Fig (4.13), it is clear that the algorithm consumes most of its time in

the inner loop. During the pass current of the outer loop size current elements are examined to

find smallest remaining elements. This requires size current 1 comparisons.

The number of comparisons for all passes is:

Size-1

(size E (n) = current 1)

current

Let k = size current 1

k = size 1 at current = 0

k = 0 at current = size 1

Size-1

kE (n) =

k=0

size(size 1)/2

n(n 1)/2 Let size = n

O( n2)

Following program segment implements the discussion. (select.c)

/* select.c */

/* selection sort */

#include <stdio.h>

#include <stdlib.h>

void selection_sort(int array[], int size)

{

int temp, current, j;

for (current = 0; current < size; current++)

for (j = current + 1; j < size; j++)

if (array[current] > array[j])

{

temp = array[current];

array[current] = array[j];

array[j] = temp;

}

}

void main(void)

{

int values[30], i;

printf("\n Unsorted list is as follows \n");

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

{

values[i] = rand() % 100;

printf(" %d", rand() %100);

}

selection_sort(values, 30);

printf("\n Sorted list is as follows \n");

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

printf("%d ", values[i]);

}

Another way to illustrate the algorithm of selection sort.

/* SELECTION SORT */

/* selects.c */

# include<stdio.h>

int selection_sort(int , int *); /* Prototype */

void main()

{

int number, list[200];

int i;

printf("Input the number of elements in the list:");

scanf("%d", &number);

printf("\n Number of elements in the list is: %d", number);

printf("\nInput the elements of the list\n");

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

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

selection_sort( number, list);

}

/* Definition of function */

int selection_sort(int n, int l[])

{

int min ;

int k, index;

for(index = 0; index< n - 1 ; index++)

{

min = index ;

for(k = index + 1; k < n ; k ++)

{

if(l[min] > l[k])

min = k ;

}

if( min != index)

{

int temp = l [index];

l[index] = l[min];

l[min] = temp ;

}

}

printf("\n Entered list is as follows:\n");

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

printf(" %d", l[index]);

return 0;

}

MERGE SORT

Suppose an array A with n elements A[1], [2], ., A[N] is in memory. The merge-sort algorithm

which sorts A will first be described by means of a specific example.

EXAMPLE 4.7

Suppose the array A contains 14 elements as follows:

66, 33, 40, 22, 55, 88, 60, 11, 80, 20, 50, 44, 77, 30

Each pass of the merge-sort algorithm will start at the beginning of the array A and merge pairs of

sorted subarrays as follows:

Pass1: Merge each pair of elements to obtain the following list of sorted pairs:

33, 66 22, 40 55, 88 11, 60 20, 80 44, 50 30, 77

Pass 2: Merge each pair of pairs to obtain the following list of sorted quadruplets:

22, 33, 40, 66 11, 55, 60, 88 20, 44, 50, 80 30,77

Pass 3: Merge each pair of sorted quadruplets to obtain the following two sorted subarrays:

11, 22, 33, 40, 55, 60, 66, 88 20, 30, 44, 50, 77, 80

Pass 4: Merge the two sorted subarrays to obtain the single sorted array

11, 20, 22, 30, 40, 44, 50, 55, 60, 66, 77, 80, 88

The original array A is now sorted.

The above merge sort algorithm for sorting an array A has the following important property. After

Pass K, the array A will be partitioned into sorted subarrays where each subarray, except possibly

the last, will contain exactly L=2k elements. Hence the algorithm requires at most log n passes to

sort an n-element array A.

The formal statement of the merge sort algorithm follows:

Algorithm MERGESORT (A, N)

This algorithm sorts the N element array A using an auxiliary array B.

1. Set L: =1. [Initializes the number of elements in the subarrays.]

2. Repeat Steps 3 to 6 while L<N:

3. Call MERGEPASS (A, N, L, B).

4. Call MERGEPASS (B, N, 2*L, A).

5. Set L: = 4 * L.

[End of Step 2 loop.]

6. Exit.

Complexity of the Merge Sort Algorithm

Let f(n) denote the number of comparisons needed to sort an n element array A using the merge

sort algorithm. Recall that the algorithm requires at most log n passes. Moreover, each pass

merges a total of n elements, and by the discussion on the complexity of merging, each pass will

require at most n comparisons. Accordingly, for both the worst case and average case,

n logf(n) n

Observe that this algorithm has the same order as heapsort and the same average order as

quicksort. The main drawback of merge-sort is that it requires an auxiliary array with n elements.

Each of the other sorting algorithms we studied requires only a finite number of extra locations,

which is independent of n.

The above results are summarized in the following table:

Algorithm Worst Case Average Case Extra Memory

Merge-Sort n log n = O (n log n) n log n = O (n log n) O (n)

Program to illustrate the merge sort

/* MERGE SORT */

/* merge.c */

# include<stdio.h>

# include<stdlib.h>

void merge_sort(float *, int , int , int );

void merge_pass(float *, int , int );

/* Definition of the function */

void merge_sort(float l[], int top, int size, int bottom)

{

float temp[1000];

int f = top;

int s = size +1 ;

int t = top ;

int upper;

while(( f <= size)&&(s <=bottom))

{

if(l[f] <= l[s])

{

temp[t] = l[f] ;

f ++;

}

else

{

temp[t] = l[s] ;

s ++;

}

t ++;

}

if(f <=size)

{

for(f = f ; f<=size; f++)

{

temp[t] = l[f];

t++;

}

}

else

{

for(s = s ; s<= bottom ; s++)

{

temp[t]=l[s];

t++;

}

}

for(upper = top; upper <= bottom ; upper++)

{

l[upper]=temp[upper];

}

}

/* Definition of the function */

void merge_pass( float append[], int m, int n )

{

if( m!= n)

{

int mid = (m+n)/2;

merge_pass( append, m, mid );

merge_pass( append, mid+1, n );

merge_sort( append, m, mid, n );

}

}

/* main function */

void main()

{

float list[1000];

int i, n = 30;

printf("\n Size of the list: %d", n);

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

{

list[i] = (float) (rand() %100);

}

printf("\n Entered list as follows:\n");

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

printf(" %d ", (int) list[i]);

i = 0 ;

merge_pass(list, i, n-1);

printf("\n Merge sorted list is as follows:\n");

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

printf(" %d", (int) list[i]);

}

RADIX SORT

Radix sort is a technique, which is usually used when large lists of names are to be sorted

alphabetically. Using this sorting technique one can classify the list of names into 26 groups. The

list is first sorted on the first letter of each name, i.e., the names are arranged in 26 classes where

the first class consists of those names that begin with alphabet A, the second class consists of

those names that begin with alphabet B and so on. During the second pass each is alphabetized

according to the second letter of the name and so on. For e.g., if no name contains more than 20

characters then the sort requires 20 passes. The radix sort is a technique, which is used by a card

sorter. A card sorter contains 13 receiving pockets labeled as

9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 11, 12, R

Here R represents reject, if any card comes in this pocket.

Each pocket other R corresponds to a row on a card in which a hole can be punched. Decimal

numbers where the radix is 10 are punched in the obvious way and hence use only the first 10

pockets on the sorter. The sorter uses a radix reverse digit sort on numbers. For e.g., suppose a

card sorter is given a collection of cards where each card contains a four- digit number punched in

columns 1 4. The cards are first sorted according to the units digit. In the second pass, the cards

sorted according to the tens digit. In the third pass the cards are sorted according to the hundreds

digit. In the fourth and last pass, the cards are sorted according to the thousands digit. For e.g.,

suppose cards are punched as shown in the Fig.

1 2 3 4 5 6 7

4348 2143 4361 5423 4538 2128 5438

Fig. (A) Punched card data

Fig (A.1)Pass 1 sort units digit

(i) Pass 1: The unit digits are sorted into pockets. The cards are collected pocket by pocket from

pocket 9 to pocket 0. The cards are now re- input to the sorter.

(ii) Pass 2: The tens digit are sorted into pockets. Again cards are collected pocket by pocket and

re- input to the sorter.

Fig.(A.2) Pass 2 sort on 10th digit

(iii) Pass 3: The 100th digits are sorted into pockets. Again cards are collected pocket by pocket

and re- input to the sorter.

Fig. (A.3) Pass 3 sort on 100th digit

(iv) Pass 4: The 1000s digits are sorted into pocket. Again cards are sorted pocket by pocket.

Fig. (A.4) Pass 4 sort on 1000s digit

Now collecting the values of pockets from 9th to 0th then we get the list of array as shown in Fig.

(B)

1 2 3 4 5 6 7

5438 5423 4538 4361 4348 2143 2128

Fig. (B) Sorted list using radix sort

From the result shown in Fig (B) , it it clear that the list is sorted in descending order.

Fig (C.1)Pass 1 sort units digit

Fig.(C.2) Pass 2 sort on 10th digit

Fig.(C.3) Pass 3 sort on 100th digit

Fig.(C.4) Pass 4 sort on 1000th digit

If during the sorting operation one collects the pocket from 0th to 9th the result will come in

ascending order. For example , Fig .(C.1 C.4) illustrates the preceding statement.

Now collecting the values of pockets from 0th to 9th , we get the list of array as shown in fig D.

1 2 3 4 5 6 7

2128 2143 4348 4361 4538 5423 5438

Fig .D Sorted list using Radix Sort.

The result shown in Fig. D denotes that the list is sorted in ascending order.

In general we can define an algorithm for radix sort as follows:

Step 1: Repeat through Step 6 for each digit in the key.

Step 2: Initialize the pockets.

Step 3: Repeat through Step 5 until end of the linked list.

Step 4: Obtain the next digit of the key.

Step 5: Insert the element in appropriate pocket.

Step 6: Combine the pockets to form a new linked list.

Suppose rec represents a list of n elements, i.e., rec1, rec2, .,recn and d denotes the radix (For

decimal number system, which is 10, for alphabets it is 26, binary it is 2, for octal number system

it is 8 etc.) and each element reci is represented by means of m digits.

reci =di1 di2 di3 dim.

The radix sort algorithm requires m pass the number of digits in each element. Pass j will

compare each dij with each of the d digits. Hence, total number of comparisons (and in turn

efficiency) is:

E(n) = d*m*n [Maximum value possible that is possible]

Where d and m are independent of n.

(i) Worst case: If n = m the E(n) = d*n*n = d*n2O(n2)

(ii) Best case: m = logd n

E(n) =d*(logd n)*n

= O( n logd n)

Algorithm to find largest number in the list

Algorithm to find number of digits in largest number in the given list

Algorithm that make links elements during Sorting

Algorithm which updates the values of the pockets

The sub-algorithm, which are necessary in the radix sort, are given in the above algorithms.

pocket [i] Represents top element in the ith pocket

Represents bottompocket1 [i] element in the ith pocket.

Represents j pass j index.

Represents pocket i index.

Represents temporary index poc variable.

Represents a pointer variable which denotes the address of the current element begin examined

in the list and begin directed to appropriate pocket.

Represents a pointer variable which denotes the address of the next element to be examined in

the list and being directed to appropriate pocket.

Represents the current digit in a key being examined.

Algorithm for radix sort

Program segment RADIX.C implements the radix sort algorithm is illustrated below:

/* RADIX SORT */

/* RADIX.C*/

# include<stdio.h>

# include<malloc.h>

# include<stdlib.h>

struct node

{

int data ;

struct node *next;

};

typedef struct node node1;

node1 *first;

node1 *pocket[100], *pocket1[100];

void create_node(node1 *, int);

void display(node1 *);

node1 *radix_sort(node1 *);

int large(node1 * );

int numdig(int );

int digit(int , int);

void update(int, node1 *);

node1 *Make_link(int, node1 *);

/* This function create nodes and take input data */

void create_node(node1 *rec, int n)

{

int i, j, k;

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

{

rec->next = (node1 *) malloc(sizeof(node1));

printf("\n First node value: %d: ", i);

scanf("%d", &rec->data);

rec = rec->next;

}

rec->next = NULL;

}

/* Output Function */

void display(node1 *rec)

{

while(rec !=NULL)

{

printf(" %d", rec->data);

rec= rec->next;

}

}

/* This radix sort function */

node1 *radix_sort(node1 *rec)

{

node1 *r, *nex;

int poc = 0 ;

int i, j, k;

int larg = large(rec);

int m = numdig(larg);

/* These statements create pockets */

for(k = 0 ; k < 10; k++)

{

pocket[k] = (node1 *)malloc(sizeof(node1));

pocket1[k] = (node1 *)malloc(9*sizeof(node1));

}

/* These statements initialize pockets */

for(j = 1; j <= m ; j++)

{

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

{

pocket[i] = NULL;

pocket1[i] = NULL ;

}

r = rec ;

while(r != NULL)

{

int dig = digit(r->data, j);

nex = r->next ;

update(dig,r);

r = nex;

}

if(r!= NULL)

{

int dig = digit(r->data,j);

update(dig,r);

}

while(pocket1[poc] == NULL)

poc ++;

rec = Make_link(poc, rec);

}

return(rec);

}

/* This function finds largest number in the list */

int large(node1 *rec)

{

node1 *save ;

int p = 0;

save = rec ;

while(save != NULL)

{

if(save ->data > p)

{

p = save->data;

}

save = save->next ;

}

printf("\n Largest element: %d", p);

return(p);

}

/* This Function finds number digits in a number */

int numdig(int large)

{

int temp = large ;

int num = 0 ;

while(temp != 0)

{

++num ;

temp = temp/10 ;

}

printf("\n Number of digits of the number %d is %d", large, num);

return(num);

}

/* This function scarve a number into digits */

int digit(int num, int j)

{

int dig, i, k;

int temp = num ;

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

{

dig = temp % 10 ;

temp = temp / 10 ;

}

printf(" %d digit of number %d is %d", j, num, dig);

return(dig);

}

/* This function updates the pockets value */

void update(int dig, node1 *r)

{

if(pocket[dig] == NULL)

{

pocket[dig] = r ;

pocket1[dig] = r ;

}

else

{

pocket[dig]->next = r ;

pocket[dig] = r ;

}

r->next = NULL;

}

/* This function create links between the nodes */

node1* Make_link(int poc , node1 *rec)

{

int i, j, k;

node1 *pointer;

rec = pocket1[poc];

for(i = poc +1 ; i< 10 ; i++)

{

pointer = pocket[i-1];

if(pocket[i] != NULL)

pointer->next= pocket1[i];

else

pocket[i] = pointer ;

}

return(rec);

}

/* Main function */

void main()

{

node1 *start, *pointer;

int number;

printf("\n Input the number of elements in the list:");

scanf("%d", &number);

start = (node1 *)malloc(sizeof(node1));

create_node(start, number);

printf("\n Given list is as follows \n");

display(start);

start = radix_sort(start);

printf("\n Sorted list is as follows:\n");

display (start);

}

- Class 11Caricato daDea Giovani Natalia
- Online Convex HullCaricato dasonal
- Interview QuestionsCaricato dajatin.s.jani4976
- Interactive Dimensioning of Parametric ModelsCaricato datwak
- Singly Linked List OperationCaricato daPawan Saini
- artificial intelligenceCaricato daAbeerHassan
- c ProgrammingsCaricato daAshish Chirania
- c Puzzle AnswersCaricato daapi-3721375
- ADS ManualCaricato dasrinidhi2all
- data stuture record.docCaricato daHemanth Kumar Rajendakumar
- Huff ManCaricato damy_scribd_docs
- Binary Search TreeCaricato daShanks1
- TR SortingCaricato daravg10
- Learning JCaricato dashabunc
- Lowest Common AncestorCaricato daRaqibul Islam
- Cs2208 Lab ManuaCaricato daSubhasini Murugesan
- Assignment4--BinaryTreesCaricato daPrachi Dabaria
- DS SyllabusCaricato daSabitha Durai
- Fastexp CopyCaricato dasalafyun
- Cs1201 Design and Analysis of AlgorithmCaricato damaharajaking
- lec14Caricato daShengFeng
- DAMAS RescueDescriptionPaper2006Caricato daanasshs
- power.docxCaricato daselvakumargeorg1722
- Binary Tree Term 1Caricato daGunjan Bhavsar
- 50 Program and AnswersCaricato daSantosh Sandy
- EI6001-Data Strucures and Algorithms QBCaricato dajgjeslin
- Sales and Operations PlanningCaricato daRanjan
- the new fundamental tree.pdfCaricato daSky Fall
- 2.txtCaricato daHieu Truong
- mtap.docxCaricato daJohnRocelPerez

- TextingCaricato daShehe24
- 100 Ways to Make Your DayCaricato daAnurag Goel
- Good Relations Are ThoseCaricato daAnurag Goel
- Intense SmileCaricato daAnurag Goel
- We EducateCaricato daAnurag Goel
- V_VI_G_SBCaricato daAnurag Goel
- Blessed Are the MomentsCaricato daAnurag Goel
- Life Lesson 1Caricato daAnurag Goel
- AndroidCaricato daAnurag Goel
- 3gCaricato daAnurag Goel
- I walkCaricato daAnurag Goel
- DonCaricato daAnurag Goel
- SYLLABUSCaricato daAnurag Goel
- HistoryCaricato daAnurag Goel
- At the End of the RainbowCaricato daAnurag Goel
- Blessed Are the MomentsCaricato daAnurag Goel
- गुस्साCaricato daAnurag Goel
- dbCaricato daAnurag Goel
- Good Relations Are ThoseCaricato daAnurag Goel
- Revision Test PPT v 2013-14Caricato daAnurag Goel
- CloudCaricato daAnurag Goel
- State Bank Collect(1)Caricato daAnurag Goel
- TCALCCaricato daMuqthiar Ali
- Business PlanCaricato daAnurag Goel
- 2.19.99 Proskauer.jenex AgreeCaricato daAnurag Goel
- HELPME!Caricato datrkiendthv
- GENCATCaricato daAnurag Goel
- Android MarketCaricato daAnurag Goel

- QUIZ-1Caricato daianguieb
- Value Based Life and EducationCaricato daE-gurukul
- 2013 Inv PresentationCaricato daganeshtsk
- Service Manual BORA 7-12KCaricato damoshul
- Gear Krieg - Axis Sourcebook.pdfCaricato daJason-Lloyd Trader
- 2011-02-08_225950_fc2215clCaricato daLuis Manuel Martinez Nuñez
- Week #48 – The Creative ProcessCaricato daGareth James Parry
- Communication of 19 December 2018 : “Preparing for the withdrawal of the United Kingdom from the European Union on 30 March 2019: Implementing the Commission’s Contingency Action Plan”Caricato daeldiario.es
- 8Caricato daaisanelb
- dm74ls283Caricato daFredy Cnnm Lnr
- piano graded piecesCaricato dawilliam_lawes
- Solution to DMOP Make Up Exam 2016Caricato daSaurabh Kumar Gautam
- Manual Para SU SystemManualBA43_V_4.0A.pdfCaricato daEdwir721
- GE2410 Student Booklet(UpdatedDec27)Caricato damarkho
- Asphalt Tests.pdfCaricato dadishku
- BUHLER BOTTLE GRADE SSP DETAILSCaricato daMK Yogi
- Message to the CCDS Community 12-7-18Caricato daCincinnatiEnquirer
- UoS Outline FINC3011 SEM1 2014Caricato daSweetCherrie
- BRK-110Caricato daCeleste Jones
- 57200438 Pest Analysis POM Assignment TATACaricato daVaibhav Gupta
- Land Titles - Judicial Confirmation of Imperfect TItle-Orig Reg StepsCaricato daBoy Kakak Toki
- Ambreen_Farooqui_118466388Caricato dazigzagzodiac
- Finacle Commands for Concurrent AuditCaricato daMayur Kundar
- The Treaty of the European Union, Maastricht Treaty, 7th February, 1992 by European UnionCaricato daGutenberg.org
- NCP-Impaired physical mobility.docCaricato daArrjhey Doge
- DISC Report with TEAMS & ValuesCaricato daPeopleKeys
- California Tax Board: 03 568bkCaricato daTaxman
- Chapter 3Caricato daTudy Rivera
- X Factor USA DetailsCaricato daJatin
- 2.4GHz RF,IF updown converter appl. note.pdfCaricato dachaparal

## Molto più che documenti.

Scopri tutto ciò che Scribd ha da offrire, inclusi libri e audiolibri dei maggiori editori.

Annulla in qualsiasi momento.