Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
16 views42 pages

DSA Notes M-1

The document provides an overview of data structures, including their definitions, classifications into primitive and non-primitive types, and operations such as traversing, searching, inserting, deleting, sorting, and merging. It elaborates on linear and non-linear data structures, arrays, structures, unions, pointers, and dynamic memory allocation in C programming. Additionally, it includes examples and syntax for implementing these concepts in C.

Uploaded by

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

DSA Notes M-1

The document provides an overview of data structures, including their definitions, classifications into primitive and non-primitive types, and operations such as traversing, searching, inserting, deleting, sorting, and merging. It elaborates on linear and non-linear data structures, arrays, structures, unions, pointers, and dynamic memory allocation in C programming. Additionally, it includes examples and syntax for implementing these concepts in C.

Uploaded by

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

DATA STRUCTURES AND APPLICATIONS 18CS32

MODULE-I

Introduction to Data Structures


Data Structure is a way of collecting and organizing data in such a way that we can perform operations
on these data in an effective way. Data Structures is about rendering data elements in terms of some
relationship, for better organization and storage. For example, we have data player's name "Virat" and
age 26. Here "Virat" is of String data type and 26 is of integer data type.
We can organize this data as a record like Player record. Now we can collect and store player's
records in a file or database as a data structure. For example: "Dhoni" 30, "Gambhir" 31, "Sehwag" 33.
➢ In simple language, Data Structures are structures programmed to store ordered data, so that
various operations can be performed on it easily.
➢ It represents the knowledge of data to be organized in memory. It should be designed and
implemented in such a way that it reduces the complexity and increases the efficiency.
➢ Data may be organized in many different ways. The logical or mathematical model of a
particular organization of data is called a data structure.

Classification of data structures (Primitive & Non Primitive)


As we have discussed above, anything that can store data can be called as a data structure.

Data structures are generally categorized into two classes:


➢ Primitive data Structures
➢ Non-primitive data Structures
Primitive Data Structures
Primitive data structures are the fundamental data types which are supported by a programming
language. Some basic data types are integer, real, character, and Boolean. The terms ‘data type’, ‘basic
data type’, and ‘primitive data type’ are often used interchangeably.
Non-Primitive Data Structures
Non-primitive data structures are those data structures which are created using primitive data
structures. Examples of such data structures include linked lists, stacks, trees, and graphs.

Based on the structure and arrangement of data, non-primitive data structures is further classified into
➢ Linear Data Structure

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 2
DATA STRUCTURES AND APPLICATIONS 18CS32

➢ Non-linear Data Structure


Linear data Structures
If the elements of a data structure are stored in a linear or sequential order, then it is a linear data
structure. Examples include arrays, linked lists, stacks, and queues.
Linear data structures can be represented in memory in two different ways.
➢ One way is to have to a linear relationship between elements by means of sequential memory
locations.
➢ The other way is to have a linear relationship between elements by means of links.
Non-linear data Structures
If the elements of a data structure are not stored in a sequential order, then it is a non-linear data
structure.
➢ The relationship of adjacency is not maintained between elements of a non-linear data
structure.
➢ This structure is mainly used to represent data containing a hierarchical relationship between
elements.
Examples include trees and graphs.

Figure (a). Classifications of Data Structures

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 3
DATA STRUCTURES AND APPLICATIONS 18CS32

Data structure Operations


Data are processed by means of certain operations which appearing in the data structure. In fact,
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 these operations.
(1) 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).
(2) Searching: Finding the location of the record with a given key value, or finding the location of all
records which satisfy one or more conditions.
(3) Inserting: Adding a new record to the structure.
(4) Deleting: Removing the record from the structure.
(5) Sorting: Arranging the data or record in some logical order (Ascending or descending order).
(6) Merging: Combining the record in two different sorted files into a single sorted file.
Review of Arrays
An array data structure, or simply an array, is a data structure consisting of a collection of (mainly
of similar data types) elements (values or variables), each identified by at least one array index or key.
An array is stored so that the position of each element can be computed from its index tuple by a
mathematical formula.
ARRAYS IN C
➢ A one-dimensional array can be declared as follows:
int list[5]; //array of 5 integers
int *plist[5]; //array of 5 pointers to integers

➢ Compiler allocates 5 consecutive memory-locations for each of the variables 'list' and 'plist'.
➢ Address of first element list [0] is called base-address.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 4
DATA STRUCTURES AND APPLICATIONS 18CS32

➢ Memory-address of list[i] can be computed by compiler as

α + i * sizeof (int) where α =base address

Program to find sum of n numbers using array


#define MAX_SIZE 100
float sum (float [], int);

float input [MAX_SIZE], answer;


int i;

main ()
{

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


input[i] = i;
answer = sum (input, MAX_SIZE);
printf("The sum is: %f\n", answer);

float sum (float list [], int n)

{
int i;

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

tempsum += list[i];
return tempsum;
}

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 5
DATA STRUCTURES AND APPLICATIONS 18CS32

Program to print both address of ith element of given array & the value found at that address.

void print1(int *ptr, int rows)


{

/* print out a one-dimensional array using a pointer */


int i;

printf(“Address Contents\n”);
for (i=0; i < rows; i++)

printf(“%8u%5d\n”, ptr+i, *(ptr+i));


printf(“\n”);

void main ()
{

int one [] = {0, 1, 2, 3, 4};


print1(&one [0], 5);

Output

Arrays are generally used when we want to store large amount of similar type of data. But they have
the following limitations:
➢ Arrays are of fixed size.
➢ Data elements are stored in contiguous memory locations which may not be always available.
➢ Insertion and deletion of elements can be problematic because of shifting of elements from
their positions.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 6
DATA STRUCTURES AND APPLICATIONS 18CS32

STRUCTURES

In C,a way to group data that permits the data to vary in type. This mechanism is called the structure,
for short struct.
A structure (a record) is a collection of data items, where each item is identified as to its type and
name.
Syntax:
struct
{
data_type member 1;
data_type member 2;
………………………
………………………
data_type member n;
} variable_name;

Ex: struct {
char name [10];
int age;
float salary;
} Person;

The above example creates a structure and variable name is Person and that has three fields:
name = a name that is a character array
age = an integer value representing the age of the person
salary = a float value representing the salary of the individual
Assign values to fields
To assign values to the fields, use. (dot) as the structure member operator. This operator is used to
select a particular member of the structure
Ex: strcpy(Person.name,“james”);
Person.age = 10;
Person.salary = 35000;
SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 7
DATA STRUCTURES AND APPLICATIONS 18CS32

Type-Defined Structure
The structure definition associated with keyword typedef is called Type-Defined Structure.
Syntax 1:
typedef struct
{
data_type member 1;
data_type member 2;
………………………
………………………
data_type member n;
} TypeName;
Where,
➢ typedef is the keyword used at the beginning of the definition and by using typedef user
defined data type can be obtained.

➢ struct is the keyword which tells structure is defined to the complier

➢ The members are declared with their data_type

➢ Type_name is not a variable; it is user defined data_type.


Syntax 2:
struct struct_name
{
data_type member 1;
data_type member 2;
………………………
………………………
data_type member n;
};
typedef struct struct_name Type_name;

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 8
DATA STRUCTURES AND APPLICATIONS 18CS32

Ex:
typedef struct
{
char name [10];
int age;
float salary;
} human Being;
In above example, humanBeing is the name of the type and it is a user defined data type.
Declarations of structure variables:
humanBeing person1, person2;
This statement declares the variable person1 and person2 are of type humanBeing.
Structure Operation
The various operations can be performed on structures and structure members.
1. Structure Equality Check:
Here, the equality or inequality check of two structure variable of same type or dissimilar type is not
allowed
typedef struct
{
char name [10];
int age;
float salary;
} humanBeing;
humanBeing person1, person2;
if (person1 = = person2) is invalid.

The valid function is shown below


#define FALSE 0
#define TRUE 1
if (humansEqual (person1, person2))
printf("The two human beings are the same\n");
else

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 9
DATA STRUCTURES AND APPLICATIONS 18CS32

printf ("The two human beings are not the same\n");


int humansEqual(humanBeing person1, humanBeing person2)
{
/* return TRUE if person1 and person2 are the same human being otherwise
return FALSE */
if (strcmp (person1.name, person2.name))
return FALSE;
if (person1.age! = person2.age)
return FALSE;
if (person1.salary! = person2.salary)
return FALSE;
return TRUE;
}
2. Assignment operation on Structure variables:
person1 = person2
The above statement means that the value of every field of the structure of person 2 is assigned as the
value of the corresponding field of person 1, but this is invalid statement.
Valid Statements is given below:
strcpy(person1.name, person2.name);
person1.age = person2.age;
person1.salary = person2.salary;
Structure within a structure:
There is possibility to embed a structure within a structure. There are 2 ways to embed structure.
1. The structures are defined separately and a variable of structure type is declared inside the definition
of another structure. The accessing of the variable of a structure type that are nested inside another
structure in the same way as accessing other member of that structure
Example: The following example shows two structures, where both the structure are defined
separately.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 10
DATA STRUCTURES AND APPLICATIONS 18CS32

typedef struct
{
int month;
int day;
int year;
} date;
typedef struct
{
char name [10];
int age;
float salary;
date dob;
} humanBeing;
humanBeing person1;
A person born on February 11, 1944, would have the values for the date struct set as:
person1.dob.month = 2;
person1.dob.day = 11;
person1.dob.year = 1944;
2. The complete definition of a structure is placed inside the definition of another structure.
Example:
typedef struct
{
char name [10];
int age;
float salary;
struct
{ int month;
int day;
int year;
} date;
} humanBeing;

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 11
DATA STRUCTURES AND APPLICATIONS 18CS32

SELF-REFERENTIAL STRUCTURES
➢ A self-referential structure is one in which one or more of its components is a pointer to itself.
➢ These require dynamic storage management routines (malloc & free) to explicitly obtain and
release memory.
typedef struct
{
char data;
struct list *link; //list is a pointer to a list structure
} list;
➢ Consider three structures and values assigned to their respective fields:
list item1, item2, item3;
item1.data='a';
item2.data='b';
item3.data='c';
item1.link=item2.link=item3.link=NULL;
➢ We can attach these structures together as follows
item1.link=&item2;
tem2.link=&item3;

INTERNAL IMPLEMENTATION OF STRUCTURES


➢ The size of an object of a struct or union type is the amount of storage necessary to represent
the largest component, including any padding that may be required.
➢ Structures must begin and end on the same type of memory boundary. For ex, an even byte
boundary (2, 4, 6 or 8).

Union
A union is a special data type available in C that allows us to store different data types in the same
memory location. You can define a union with many members, but only one member can contain a
value at any given time. Unions provide an efficient way of using the same memory location for
multiple-purpose.
SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 12
DATA STRUCTURES AND APPLICATIONS 18CS32

#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str [20];
};
int main ()
{
union Data data;
printf (“Memory size occupied by data: %d\n", sizeof(data));
return 0;
}
The memory occupied by a union will be large enough to hold the largest member of the union. For
example, in the above example, Data type will occupy 20 bytes of memory space because this is the
maximum space which can be occupied by a character string.
POINTERS

➢ In computer science, a pointer is a programming language data type whose value refers directly
to (or "points to") another value stored elsewhere in the computer memory using its address.
➢ This is a memory-location which holds the address of another memory-location.
➢ The 2 most important operators used w.r.t pointer are:
& (address operator)
* (dereferencing/indirection operator)
#include<stdio.h>
void main ()
{
int a=10, b=20; //Declare a data variable
int *p, *q; //Declare a pointer variable
int p=&a, q=&b; //Initialize a pointer variable
int x=*p + *q;
printf("%d+%d=%d",*p,*q, x); //Access data using pointer variable
}

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 13
DATA STRUCTURES AND APPLICATIONS 18CS32

NULL POINTER
➢ The null pointer points to no object or function.
i.e. it does not point to any part of the memory.
if(p==NULL)
printf("p does not point to any memory");
else
printf("access the value of p");

DYNAMIC MEMORY ALLOCATION


➢ This is process of allocating memory-space during execution-time (or run-time).
➢ This is used if there is an unpredictable storage requirement.
➢ Memory-allocation is done on a heap.
➢ Memory management functions include:
▪ malloc (memory allocate)
▪ calloc (contiguous memory allocate)
▪ realloc (resize memory)
▪ free (de-allocate memory)
➢ malloc function is used to allocate required amount of memory-space during run-time.
➢ If memory allocation succeeds, then address of first byte of allocated space is returned. If
memory allocation fails, then NULL is returned.
➢ free () function is used to de-allocate (or free) an area of memory previously allocated by
malloc () or calloc().
#include<stdio.h>
void main ()
{
int i, *pi;
pi=(int*) malloc(sizeof(int));
*pi=1024;
printf("an integer =%d",pi);
free(pi);
}
➢ If we frequently allocate the memory space, then it is better to define a macro as shown below:

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 14
DATA STRUCTURES AND APPLICATIONS 18CS32

#define MALLOC(p,s) \
if (! ((p)==malloc(s))) \
{ \
printf("insufficient memory"); \
exit (0); \
}

➢ Now memory can be initialized using following:


MALLOC (pi,sizeof(int));

MALLOC (pf,sizeof(float));

DANGLING REFERENCE

➢ Whenever all pointers to a dynamically allocated area of storage are lost, the storage is lost to
the program. This is called a dangling reference.

POINTERS CAN BE DANGEROUS

1) Set all pointers to NULL when they are not actually pointing to an object. This makes sure that you
will not attempt to access an area of memory that is either
→ out of range of your program or
→ that does not contain a pointer reference to a legitimate object.

2) Use explicit type casts when converting between pointer types.

pi=malloc(sizeof(int)); //assign to pi a pointer to int

pf=(float*) pi; //casts an ‘int’ pointer to a ‘float’ pointer

3) Pointers have same size as data type 'int'. Since int is the default type specifier, some programmers
omit return type when defining a function. The return type defaults to ‘int’ which can later be
interpreted as a pointer. Therefore, programmer has to define explicit return types for
functions.
void swap (int *p, int *q) //both parameters are pointers to ints
{
int temp=*p; //declares temp as an int and assigns to it the contents of what p points to *p=*q;
//stores what q points to into the location where p points
*q=temp; //places the contents temp in location pointed to by q

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 15
DATA STRUCTURES AND APPLICATIONS 18CS32

Representation of Linear Arrays in Memory


The elements of linear array are stored in consecutive memory locations. It is shown below:

DYNAMICALLY ALLOCATED ARRAYS


ONE-DIMENSIONAL ARRAYS
• When writing programs, sometimes we cannot reliably determine how large an array must be.
• A good solution to this problem is to
➢ defer this decision to run-time &
➢ Allocate the array when we have a good estimate of required array-size.

Dynamic memory allocation can be performed as follows:


int i,n,*list;
printf("enter the number of numbers to generate");
scanf("%d",&n);
if(n<1)
{
printf("improper value");
exit(0);
}
MALLOC (list, n*sizeof(int));

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 16
DATA STRUCTURES AND APPLICATIONS 18CS32

• The above code would allocate an array of exactly the required size and hence would not result in
any wastage.
TWO DIMENSIONAL ARRAYS

• These are created by using the concept of array of arrays.


• A 2-dimensional array is represented as a 1-dimensional array in which each element has a pointer
to a 1-dimensional array as shown below
int x [5][7]; //we create a 1-dimensional array x whose length is 5;
//each element of x is a 1-dimensional array whose length is 7.

• Address of x[i][j] = x[i]+j*sizeof(int)

Array-of-arrays representation

Dynamically create a two-dimensional array

Int ** make2darry (int rows, int cols)


{
Int **x,i;
/* get memory for new pointer*/
MALLOC (x, rows * sizeof (*x));

/* get memory for each row*/


for (i=0; i<rows; i++)
MALLOC(x[i], cols*sizeof (**x));
return x;
}
CALLOC
• These functions
→ allocate user-specified amount of memory &
→ Initialize the allocated memory to 0.
• On successful memory-allocation, it returns a pointer to the start of the new block.
On failure, it returns the value NULL.
• Memory can be allocated using calloc as shown below:

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 17
DATA STRUCTURES AND APPLICATIONS 18CS32

int *p;
p=(int*) calloc (n, sizeof(int)); //where n=array size

• To create clean and readable programs, a CALLOC macro can be created as shown below:

REALLOC
#define CALLOC(p,n,s) \
if((p=calloc(n,s))==NULL) \
{ \
printf("insufficient memory"); \
exit (0); \
}
• These functions resize memory previously allocated by either malloc or calloc.
For example,
realloc(p,s); //this changes the size of memory-block pointed at by p to s.
• When s>oldSize, the additional s-oldSize have an unspecified value and
when s<oldSize, the rightmost oldSize-s bytes of old block are freed.
• On successful resizing, it returns a pointer to the start of the new block. On failure, it returns the
value NULL.
• To create clean and readable programs, the REALLOC macro can be created as shown below

#define REALLOC(p,s) \
if((p=realloc(p,s))==NULL) \
{ \
printf("insufficient memory"); \
exit (0); \
}

ARRAY OPERATIONS
1. Traversing
➢ Let A be a collection of data elements stored in the memory of the computer. Suppose if the
contents of the each elements of array A needs to be printed or to count the numbers of
elements of A with a given property can be accomplished by Traversing.
➢ Traversing is a accessing and processing each element in the array exactly once.
Algorithm 1: (Traversing a Linear Array)
Hear LA is a linear array with the lower bound LB and upper bound UB. This algorithm traverses LA
applying an operation PROCESS to each element of LA using while loop.
1. [Initialize Counter] set K:= LB

2. Repeat step 3 and 4 while K ≤ UB


SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 18
DATA STRUCTURES AND APPLICATIONS 18CS32

Representation of Two-Dimensional Arrays in Memory


Let A be a two-dimensional m x n array. Although A is pictured as a rectangular array of elements
with m rows and n columns, the array will be represented in memory by a block of m . n sequential
memory locations.
The programming language will store the array A either (1) column by column, is called column-
major order, or (2) row by row, in row-major order.

Polynomials
• A polynomial is a sum of terms, where each term has a form axe,
Where x=variable, a=coefficient and e=exponent.
For ex,
A(x)=3x20+2x5+4 and B(x)=x4+10x3+3x2+1
• The largest (or leading) exponent of a polynomial is called its degree.
• Assume that we have 2 polynomials,
A(x)= ∑ai xi &
B(x)= ∑bi xi then A(x)+B(x)= ∑ (ai + bi) xi

POLYNOMIAL REPRESENTATION: FIRST METHOD

#define MAX_DEGREE 100


typedef struct
{
int degree;
float coef [MAX_DEGREE];} polynomial;

polynomial a;

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 27
DATA STRUCTURES AND APPLICATIONS 18CS32

Initial version of padd function

/* d =a + b, where a, b, and d are polynomials */


d = Zero ()
while (! IsZero(a) &&! IsZero(b)) do
{
switch COMPARE (Lead_Exp(a), Lead_Exp(b))
{
case -1: d = Attach (d, Coef (b, Lead_Exp(b)), Lead_Exp(b));
b = Remove (b, Lead_Exp(b));
break;
case 0: sum = Coef (a, Lead_Exp (a)) + Coef (b, Lead_Exp(b));
if (sum)
{
Attach (d, sum, Lead_Exp(a));
a = Remove(a , Lead_Exp(a));
b = Remove(b , Lead_Exp(b));
}
break;
case 1: d = Attach (d, Coef (a, Lead_Exp(a)), Lead_Exp(a));
a = Remove (a, Lead_Exp(a));
}
}
insert any remaining terms of a or b into d

• If a is of type ‘polynomial’ then A(x)= ∑ai xi can be represented as:


a.degree=n a.coeff[i]=a n-i
• In this representation, we store coefficients in order of decreasing exponents, such that a.coef[i] is
the coefficient of xn-i provided a term with exponent n-i exists; otherwise, a.coeff[i]=0
• Disadvantage: This representation wastes a lot of space.
For instance, if a.degree<<MAX_DEGREE and polynomial is sparse, then we will not need most of the
positions in a.coef[MAX_DEGREE] (sparse means number of terms with non-zero coefficient is small
relative to degree of the polynomial).
POLYNOMIAL REPRESENTATION: SECOND METHOD
#define MAX_TERMS 100
typedef struct
{ float coef;
int expon;
} polynomial;
polynomial terms [MAX_TERMS];
int avail=0;

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 28
DATA STRUCTURES AND APPLICATIONS 18CS32

• A(x)=2x1000+1 and B(x)=x4+10x3+3x2+1 can be represented as shown below.

Fig A. Array representation of two polynomials

• startA & startB give the index of first term of A and B respectively.
• finishA & finishB give the index of the last term of A & B respectively.
avail gives the index of next free location in the array.
• Any polynomial A that has ‘n’ non-zero terms has startA & finishA such that finishA=startA+n-1
• Advantage: This representation solves the problem of many 0 terms since A(x)-2x1000+1 uses only 6
units of storage (one for startA, one for finishA, 2 for the coefficients and 2 for the exponents)
• Disadvantage: However, when all the terms are non-zero, the current representation requires
about twice as much space as the first one.

POLYNOMIAL ADDITION

Function to add two polynomials


void padd (int starta, int finisha, int startb, int finishb,int * startd, int *finishd)
{
/* add A(x) and B(x) to obtain D(x) */ float coefficient;
*startd = avail;
while (starta <= finisha && startb <= finishb)
{
switch (COMPARE (terms[starta].expon, terms[startb].expon))
{
case -1: /* a expon < b expon */
attach(terms[startb].coef, terms[startb].expon);
startb++
break;
case 0: /* equal exponents */
coefficient = terms[starta].coef + terms[startb].coef;
if (coefficient)
attach (coefficient, terms[starta].expon);
starta++;
startb++;
break;
case 1: /* a expon > b expon */

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 29
DATA STRUCTURES AND APPLICATIONS 18CS32

attach(terms[starta].coef, terms[starta].expon); starta++;


}
}
/* add in remaining terms of A(x) */
for (; starta <= finisha; starta++)
attach(terms[starta].coef, terms[starta].expon);
/* add in remaining terms of B(x) */
for (; startb <= finishb; startb++)
attach(terms[startb].coef, terms[startb].expon);
*finishd =avail -1;

Function to add a new term

void attach (float coefficient, int exponent)


{
/* add a new term to the polynomial */
if (avail >= MAX_TERMS)
{
fprintf(stderr, “Too many terms in the polynomial\n”);
exit (0);
}
terms[avail].coef = coefficient;
terms[avail++].expon = exponent;
}
SPARSE MATRICES
• Sparse matrix contains many zero entries.
• When a sparse matrix is represented as a 2-dimensional array, we waste space.
• For ex, if 100*100 matrixes contain only 100 entries then we waste 9900 out of 10000 memory
spaces.
• Solution: Store only the non-zero elements.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 30
DATA STRUCTURES AND APPLICATIONS 18CS32

SPARSE MATRIX REPRESENTATION


• We can classify uniquely any element within a matrix by using the triple <row,col,value>. Therefore,
we can use an array of triples to represent a sparse matrix.

SpareMatrix Create(maxRow,maxCol) ::=

#define MAX_TERMS 101

typedef struct term

int col;

int row;

int value;

} term;

term a[MAX_TERMS];

Sparse matrix and its transpose stored as triples

• a[0].row contains the number of rows; a[0].col contains number of columns and
a[0].value contains the total number of nonzero entries.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 31
DATA STRUCTURES AND APPLICATIONS 18CS32

TRANSPOSING A MATRIX
• To transpose a matrix, we must interchange the rows and columns.
• Each element a[i][j] in the original matrix becomes element b[j][i] in the transpose matrix.
• Algorithm To transpose a matrix:
for all elements in column j
place element <i,j,value>
in element <j,i,value>

TRANSPOSE OF A SPARSE MATRIX

void transpose (term a [], term b [])


{
/* b is set to the transpose of a */
int n, i, j, currentb;
n = a[0].value; /* total number of elements */ b[0].row
= a[0].col; /* rows in b = columns in a */
b[0].col = a[0].row; /*columns in b = rows in a */ b[0].value =
n;
if (n > 0)
{ /*non zero matrix */
currentb = 1;
for (i = 0; i < a [0]. col; i++) /* transpose by columns in a */
for (j = 1; j <= n; j++) /* find elements from the current column */
if (a[j]. col == i)
{ /* element is in current column, add it to b */
b[currentb]. row = a[j]. col;
b[currentb]. col = a[j]. row;
b[currentb].value = a[j].value;
currentb++
}
}
}

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 32
DATA STRUCTURES AND APPLICATIONS 18CS32

Strings
➢ A string is a sequence of characters. In computer science, strings are more often used than
numbers. We have all used text editors for editing programs and documents. Some of the
Important Operations which are used on strings are: searching for a word, find -and -replace
operations, etc.
➢ There are many functions which can be defined on strings. Some important functions are

• String length: Determines length of a given string.


• String concatenation: Concatenation of two or more strings.
• String copy: Creating another string which is a copy of the original or a copy of a part
of the original.
• String matching: Searching for a query string in given string.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 33
DATA STRUCTURES AND APPLICATIONS 18CS32

The following declaration and initialization create a string consisting of the word "Hello". To hold the
null character at the end of the array, the size of the character array containing the string is one more
than the number of characters in the word "Hello."
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
If you follow the rule of array initialization then you can write the above statement as follows −
char greeting [] = "Hello";

Following is the memory presentation of the above defined string in C

Note: Actually, you do not place the null character at the end of a string constant. The C compiler
automatically places the '\0' at the end of the string when it initializes the array.

Basic Terminology
Basic Terminology each programming language contains a character set that is used to communicate
with the computer. This set usually includes the following:

A finite sequence S of zero or more characters is called a string. The number of characters in a string is
called its length. The string with zero characters is called the empty string or the null string. Specific
strings will be denoted by enclosing their characters in single quotation marks. The quotation marks
will also serve as string delimiters. Hence
‘THE END’ ‘HELLO’ ‘WELCOME’

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 34
DATA STRUCTURES AND APPLICATIONS 18CS32

PATTERN MATCHING ALGORITHMS


Pattern matching is the problem of deciding whether or not a given string pattern P appears in a string
text T. The length of P does not exceed the length of T.
First Pattern Matching Algorithm
➢ The first pattern matching algorithm is one in which comparison is done by a given pattern P
with each of the substrings of T, moving from left to right, until a match is found.
WK = SUBSTRING (T, K, LENGTH (P))
➢ Where, WK denote the substring of T having the same length as P and beginning with the Kth
character of T.
➢ First compare P, character by character, with the first substring, W1. If all the characters are the
same, then P = W1 and so P appears in T and INDEX (T, P) = 1.
➢ Suppose it is found that some character of P is not the same as the corresponding character of
W1. Then P ≠ W1

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 40
DATA STRUCTURES AND APPLICATIONS 18CS32

Complexity
The complexity of this pattern matching algorithm is equal to O (n2)

Second Pattern Matching Algorithm


The second pattern matching algorithm uses a table which is derived from a particular pattern P but is
independent of the text T.
For definiteness, suppose
P = aaba
This algorithm contains the table that is used for the pattern P = aaba.
The table is obtained as follows.
➢ Let Qi denote the initial substring of P of length i, hence Q0 = A, Q1 = a, Q2 = a2, Q3 = aab,
Q4 = aaba = P (Here Q0 = A is the empty string.)
➢ The rows of the table are labeled by these initial substrings of P, excluding P itself.
➢ The columns of the table are labeled a, b and x, where x represents any character that doesn't
appear in the pattern P.
➢ Let f be the function determined by the table; i.e., let f (Qi, t) denote the entry in the table in
row Qi and column t (where t is any character). This entry f (Qi, t) is defined to be the largest Q
that appears as a terminal substring in the string (Qi t) the concatenation of Qi and t.

For example,
a2 is the largest Q that is a terminal substring of Q2a = a3, so f (Q2, a) = Q2
A is the largest Q that is a terminal substring of Q1b = ab, so f (Q1, b) = Q0
a is the largest Q that is a terminal substring of Q0a = a, so f (Q0, a) = Q1
A is the largest Q that is a terminal substring of Q3a = a3bx, so f (Q3, x) = Q0

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 42
DATA STRUCTURES AND APPLICATIONS 18CS32

Pattern matching by checking end indices first

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 45
DATA STRUCTURES AND APPLICATIONS 18CS32

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 46
DATA STRUCTURES AND APPLICATIONS 18CS32

Knuth, Morris, Pratt Pattern Matching algorithm.

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 47
DATA STRUCTURES AND APPLICATIONS 18CS32

SATHISHA M S and SURESHA D DEPT of CSE CANARA ENGINEERING COLLEGE, MANGALURU Page 48
DATA STRUCTURES AND APPLICATIONS 18CS32

STACKS
DEFINITION
“A stack is an ordered list in which insertions (pushes) and deletions (pops) are made at one
end called the top.”
Given a stack S= (a0, ... ,an-1), where a0 is the bottom element, an-1 is the top element, and ai is
on top of element ai-1, 0 < i < n.

Figure: Inserting and deleting elements in a stack


As shown in above figure, the elements are added in the stack in the order A, B, C, D, E,
then E is the first element that is deleted from the stack and the last element is deleted from
stack is A. Figure illustrates this sequence of operations.
Since the last element inserted into a stack is the first element removed, a stack is also known
as a Last-In-First-Out (LIFO) list.

ARRAY REPRESENTATION OF STACKS


• Stacks may be represented in the computer in various ways such as one-way linked list
(Singly linked list) or linear array.
• Stacks are maintained by the two variables such as TOP and MAX_STACK_ SIZE.
• TOP which contains the location of the top element in the stack. If TOP= -1, then it indicates
stack is empty.
• MAX_STACK_SIZE which gives maximum number of elements that can be stored in stack.

Stack can represented using linear array as shown below

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 2


DATA STRUCTURES AND APPLICATIONS 18CS32

STACK OPERATIONS
Implementation of the stack operations as follows.
1. Stack Create
Stack CreateS(maxStackSize )::=
#define MAX_STACK_ SIZE 100 /* maximum stack size*/
typedef struct
{
int key;
/* other fields */
} element;
element stack[MAX_STACK_SIZE]; int top = -1;

The element which is used to insert or delete is specified as a structure that consists of only a
key field.

2. Boolean IsEmpty(Stack)::= top < 0;

3. Boolean IsFull(Stack)::= top >= MAX_STACK_SIZE-1;


The IsEmpty and IsFull operations are simple, and is implemented directly in the program
push and pop functions. Each of these functions assumes that the variables stack and top are
global.

4. Push( )
Function push checks whether stack is full. If it is, it calls stackFull( ), which prints an error
message and terminates execution. When the stack is not full, increment top and assign item
to stack [top].

void push(element item)


{ /* add an item to the global stack */
if (top >= MAX_STACK_SIZE-1)
stackFull();
stack[++top] = item;
}

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 3


DATA STRUCTURES AND APPLICATIONS 18CS32

5. Pop( )
Deleting an element from the stack is called pop operation. The element is deleted only from
the top of the stack and only one element is deleted at a time.
element pop ( )
{ /*delete and return the top element from the stack */
if (top == -1)
return stackEmpty(); /*returns an error key */
return stack[top--];
}
6. stackFull( )
The stackFull which prints an error message and terminates execution.
void stackFull()
{
fprintf(stderr, "Stack is full, cannot add element");
exit(EXIT_FAILURE);
}

STACKS USING DYNAMIC ARRAYS


The array is used to implement stack, but the bound (MAX_STACK_ SIZE) should be known
during compile time. The size of bound is impossible to alter during compilation hence this
can be overcome by using dynamically allocated array for the elements and then increasing
the size of array as needed.
Stack Operations using dynamic array
1. Stack CreateS( )::=
typedef struct
{
int key; /* other fields */
} element;
element *stack;
MALLOC(stack, sizeof(*stack));
int capacity= 1;
int top= -1;
2. Boolean IsEmpty(Stack)::= top < 0;
3. Boolean IsFull(Stack)::= top >= capacity-1;

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 4


DATA STRUCTURES AND APPLICATIONS 18CS32

4. push()
Here the MAX_STACK_SIZE is replaced with capacity
void push(element item)
{ /* add an item to the global stack */
if (top >= capacity-1)
stackFull();
stack[++top] = item;
}
5. pop( )
In this function, no changes are made.
element pop ( )
{ /* delete and return the top element from the stack */
if (top == -1)
return stackEmpty(); /* returns an error key */
return stack[top--];
}
6. stackFull( )
The new code shown below, attempts to increase the capacity of the array stack so that new
element can be added into the stack. Before increasing the capacity of an array, decide what
the new capacity should be.
In array doubling, array capacity is doubled whenever it becomes necessary to increase the
capacity of an array.
void stackFull()
{
REALLOC (stack, 2*capacity*sizeof(*stack));
capacity *= 2;
}
Stack full with array doubling
Analysis
In the worst case, the realloc function needs to allocate 2*capacity*sizeof (*stack) bytes of
memory and copy capacity *sizeof (*stack)) bytes of memory from the old array into the new
one. Under the assumptions that memory may be allocated in O(1) time and that a stack element
can be copied in O(1) time, the time required by array doubling is O(capacity).
Initially, capacity is 1.

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 5


DATA STRUCTURES AND APPLICATIONS 18CS32

Suppose that, if all elements are pushed in stack and the capacity is 2k for some k, k>O, then
the total time spent over all array doublings is O(∑𝒌𝒊=𝟏 𝟐𝒊) = O(2 k+l ) = O(2 k ).
Since the total number of pushes is more than 2k-1, the total time spend in array doubling is
O(n), where n is the total number of pushes. Hence, even with the time spent on array doubling
added in, the total run time of push over all n pushes is O(n).

STACK APPLICATIONS: POLISH NOTATION


Expressions: It is sequence of operators and operands that reduces to a single value after
evaluation is called an expression.
X=a/b–c+d*e–a*c
In above expression contains operators (+, –, /, *) operands (a, b, c, d, e).
Expression can be represented in in different format such as
 Prefix Expression or Polish notation
 Infix Expression
 Postfix Expression or Reverse Polish notation
Infix Expression: In this expression, the binary operator is placed in-between the operand. The
expression can be parenthesized or un- parenthesized.
Example: A + B
Here, A & B are operands and + is operand
Prefix or Polish Expression: In this expression, the operator appears before its operand.
Example: + A B
Here, A & B are operands and + is operand
Postfix or Reverse Polish Expression: In this expression, the operator appears after its
operand.
Example: A B +
Here, A & B are operands and + is operand

Precedence of the operators


The first problem with understanding the meaning of expressions and statements is finding out
the order in which the operations are performed.

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 6


DATA STRUCTURES AND APPLICATIONS 18CS32

Example: assume that a =4, b =c =2, d =e =3 in below expression


X=a/b–c+d*e–a*c
((4/2)-2) + (3*3)-(4*2) (4/ (2-2 +3)) *(3-4)*2
=0+9-8 = (4/3) * (-1) * 2
=1 OR = -2.66666
The first answer is picked most because division is carried out before subtraction, and
multiplication before addition. If we wanted the second answer, write expression differently
using parentheses to change the order of evaluation
X= ((a / ( b – c + d ) ) * ( e – a ) * c
In C, there is a precedence hierarchy that determines the order in which operators are evaluated.
Below figure contains the precedence hierarchy for C.

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 7


DATA STRUCTURES AND APPLICATIONS 18CS32

• The operators are arranged from highest precedence to lowest. Operators with highest

precedence are evaluated first.


• The associativity column indicates how to evaluate operators with the same precedence. For
example, the multiplicative operators have left-to-right associativity. This means that the
expression a * b / c % d / e is equivalent to ( ( ( ( a * b ) / c ) % d ) / e )
• Parentheses are used to override precedence, and expressions are always evaluated from the
innermost parenthesized expression first.

INFIX TO POSTFIX CONVERSION


An algorithm to convert infix to a postfix expression as follows:
1. Fully parenthesize the expression.
2. Move all binary operators so that they replace their corresponding right parentheses.
3. Delete all parentheses.

Example: Infix expression: a/b -c +d*e -a*c


Fully parenthesized : ((((a/b)-c) + (d*e))-a*c))
:ab/e–de*+ac*
Example [Parenthesized expression]: Parentheses make the translation process more difficult
because the equivalent postfix expression will be parenthesis-free.
The expression a*(b +c)*d which results abc +*d* in postfix. Figure shows the translation
process.

• The analysis of the examples suggests a precedence-based scheme for stacking and
unstacking operators.

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 8


DATA STRUCTURES AND APPLICATIONS 18CS32

• The left parenthesis complicates matters because it behaves like a low-precedence operator
when it is on the stack and a high-precedence one when it is not. It is placed in the stack
whenever it is found in the expression, but it is unstacked only when its matching right
parenthesis is found.
• There are two types of precedence, in-stack precedence (isp) and incoming precedence (icp).

Typedef enum { lparen rparen, plus, minus, times, divide, mod, eos, operand} precedence;
Precendence getToken(char *symbol, int *n)
{/*get the next token, symbol is the character representation, which is returned, the token is
represented by its enumerated value, which is returned in the function name*/
*symbol=expr[(*n)++];
switch(*symbol)
{
case ‘(‘: return lparen;
case ‘)‘: return rparen;
case ‘+‘: return lparen;
case ‘-‘: return minus;
case ‘/‘: return divide;
case ‘*‘: return times;
case ‘%‘: return mod;
case ‘ ‘: return eos;
default: return operand;
}
}

The declarations that establish the precedence’s are:


/* isp and icp arrays-index is value of precedence lparen rparen, plus, minus, times, divide,
mod, eos */
int isp[] = {0,19,12,12,13,13,13,0};
int icp[] = {20,19,12,12,13,13,13,0};
void postfix(void)
{
char symbol; precedence token;
int n = 0,top = 0; /* place eos on stack */

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 9


DATA STRUCTURES AND APPLICATIONS 18CS32

stack[0] = eos;
for (token = getToken(&symbol, &n); token != eos; token = getToken(&symbol,& n ))
{
if (token == operand)
printf("%c", symbol);
else if (token == rparen)
{
while (stack[top] != lparen)
printToken(pop( ));
pop( );
}
else {
while(isp[stack[top]] >= icp[token])
printToken(pop());
push(token);
}
}
while((token = pop ())!= eos)
printToken(token);
printf("\n");
}
Program: Function to convert from infix to postfix
Analysis of postfix: Let n be the number of tokens in the expression. Ө (n) time is spent
extracting tokens and outputting them. Time is spent in the two while loops, is Ө (n) as the
number of tokens that get stacked and unstacked is linear in n. So, the complexity of function
postfix is Ө (n).

EVALUATION OF POSTFIX EXPRESSION


• The evaluation process of postfix expression is simpler than the evaluation of infix
expressions because there are no parentheses to consider.
• To evaluate an expression, make a single left-to-right scan of it. Place the operands on a
stack until an operator is found. Then remove from the stack, the correct number of operands
for the operator, perform the operation, and place the result back on the stack and continue

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 10


DATA STRUCTURES AND APPLICATIONS 18CS32

this fashion until the end of the expression. We then remove the answer from the top of the
stack.

int eval(void)
{
precedence token;
char symbol;
int opl,op2, n=0;
int top= -1;
token = getToken(&symbol, &n);
while(token! = eos)
{
if (token == operand)
push(symbol-'0'); /* stack insert */
else {
op2 = pop(); /* stack delete */
opl = pop();
switch(token) {
case plus: push(opl+op2);
break;
case minus: push(opl-op2);
break;
case times: push(opl*op2);
break;
case divide: push(opl/op2);
break;
case mod: push(opl%op2);
}
}
token = getToken(&symbol, &n);
}
return pop(); /* return result */
}
Program: Function to evaluate a postfix expression

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 11


DATA STRUCTURES AND APPLICATIONS 18CS32

precedence getToken(char *symbol, int *n)


{
*symbol = expr[(*n)++];
switch (*symbol)
{
case '(' : return lparen;
case ')' : return rparen;
case '+' : return plus;
case '-' : return minus;
case '/' : return divide;
case '*' : return times;
case '%' : return mod;
case ' ' : return eos;
default: return operand;
}
}
Program: Function to get a token from the input string
• The function eval ( ) contains the code to evaluate a postfix expression. Since an operand
(symbol) is initially a character, convert it into a single digit integer.
• To convert use the statement, symbol-'0'. The statement takes the ASCII value of symbol
and subtracts the ASCII value of '0', which is 48, from it. For example, suppose symbol =
'1. The character '1' has an ASCII value of 49. Therefore, the statement symbol-'0' produces
as result the number 1.
• The function getToken( ), obtain tokens from the expression string. If the token is an
operand, convert it to a number and add it to the stack. Otherwise remove two operands
from the stack, perform the specified operation, and place the result back on the stack. When
the end of expression is reached, remove the result from the stack.

SURESHA D and SATHISHA M S DEPT. of CSE, CANARA ENGINEERING COLLEGE, MANGALURU 12

You might also like