Cs3353-Ln Notes
Cs3353-Ln Notes
Cs3353-Ln Notes
Syllabus
The data type, of a variable determines a set of values that a variable might take and
aset of operations that can be applied to those values.
Data type refer to the type and size of data associated with the variable and functions.
Allows 6 digits
after decimal
point.
double 8 -1.7e-308 to +1.7e308 %lf
Allows 15 digits
after decimal
point.
long double 10 -1.7e-4932 to 1.7e4932 %LF
Allows 15 digits
after decimal
point.
/*Program*/
#include<stdio.h>
int main()
{
char a;
unsigned char
b; int i;
unsigned int
j; long int k;
unsigned long int
m; float x;
double y
long double z;
return 0;
}
The specifiers and qualifiers for the data types can be broadly classified into
three types
Size qualifiers alter the size of the basic data types. There are two such qualifiers that can
be used with the data type int; these are short and long.
short, when placed in front of the data type int declaration, tells the C compiler that the
particular variable being declared is used to store fairly small integer values. Long specifies it
is a very big integer value.Long integers require twice the memory of than small ints.
or unsigned long
unsigned long long int 8 0 to + 18, 446, 744, 073,709, 551, 615
Sign specifiers: for example fot int data type out of 2bytes(2*8=16bits) of its size the
highest bit(the sixtheenth bit) is used to store the sign of the integer value. The bit is 1 if
number is negative and 0 if the number is positive.
Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit Bit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Sign of number
(1 for –ve and 0
for +ve0
Type qualifiers : There are two type qualifiers, const and volatile;
Eg: const float pi = 3.14156; // specifies that the variable pi can never be changed
bythe Program.
Table:Size and range in (16-bit machines)
Allowed combinations of basic data types and modifi ers in C for a 16-bit
computer
STUDENTSFOCUS
www.Vidyarthiplus.com
VARIABLES
Variable is the name of memory location which holds the data. Unlike constant, variables
are changeable, value of a variable can be changed during execution of a program. A
programmer must chose a meaningful variable name.
Variables are used for holding data values so that they can be utilized for various
computations in a program.A variable must be declaed and then used for coputation work in
program./A variable is an identifier used for storing and holding some data(value).
1.A data type: Like int, double, float. Once defined,the type of a C variable
cannot be changed.
2.A name of the variable.
3.A value that can be changed by assigning a new value to the variable. The
kind of values a variable can assume depends on its type.
Eg : for variable int salary,it can only take integer values can only take integer
values like 65000 and not 6500.0
Declaration of a variable must be done before it is used for any computation inhte
program.
Declaration tells the compiler what the variable name is.
Declaration tells what type of data the variable will hold.
Until the variable is not defined/or/declared compiler will not allocate memory space tothe
variables.
A variable can also be declared outside main() function.
A variable can also be declared in other program and declared using extern keyword.
int yearly_salary;
float monthly_salary;
int a;
double x;
int ECE1111;
Initializing a variable:=
Initializing a variable means to provide a value to variable
Variables are a way of reserving memory to hold some data and assign names to them so
that we don’t have to remember the numbers like REG46735 or memory address like
FFFFoxFF and instead we can use the memory location by simply referring to the variable.
Arithmetic Operators
Relational Operators
Logical Operators
Bitwise Operators
Assignment Operators
Special Operators
Arithmetic Operators
The following table shows all the arithmetic operators supported by the C language.
Assume variable A holds 10 and variable B holds 20
Relational Operators
Following table shows all the logical operators supported by C language. Assume variable A
holds 1 and variable B holds 0, then −
Bitwise Operators
Bitwise operator works on bits and perform bit-by-bit operation. The truth tables for &, |, and ^ is as follows −
P q p&q p|q p^q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Assume A = 60 and B = 13 in binary format, they will be as follows −
A = 0011 1100
B = 0000 1101
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
The following table lists the bitwise operators supported by C. Assume variable 'A' holds 60 and variable 'B'
holds 13, then −
Operator Description Example
Binary AND
& (A & B) = 12, i.e., 0000 1100
It takes 1 if both operands has value 1.
Binary OR
Operator copies a bit if it exists in either operan
| (A | B) = 61, i.e., 0011 1101
The output of bitwise OR is 1 if at least one
corresponding bit of two operands is 1.
Binary XOR
^ 1 if the corresponding bits of two operands are (A ^ B) = 49, i.e., 0011 0001
opposite
Binary Ones Complement
~ (~A ) = -60, i.e,. 1100 0100
'flipping' bits- 0 changed to 1and 1 changed to 0
Binary Left Shift Operator.
<< The left operands value is moved left by the A << 2 = 240 i.e., 1111 0000
number of bits specified by the right
operand.
Binary Right Shift Operator.
>> The left operands value is moved right by the A >> 2 = 15 i.e., 0000 1111
number of bits specified by the right operand.
Assignment Operators
The following table lists the assignment operators supported by the C language
special Operators
Expression
Eg : c+d
x/y+b+a*a*a
3.14 *r *r
#include<stdio
.h> int main()
{
int num1,num2,num3;
if((a>b)&&(a>c))
printf("\n %d is
greatest",a); else if(b>c)
printf("\n %d is greatest",b
"); else
printf("\n %d is
greatest",c); return 0;
}
Output = 21
complement = 220
OutputAND = 8
OutputOR = 29
Decision Making and Branching
if(test-expression)
It allows the computer to evaluate the expression first and them depending on whether
the value of the expression is "true" or "false", it transfer the control to a particular
statements. This point of program has two paths to flow, one for the true and the other
for the false condition.
if(test-expression)
statement-block
statement-x;
p4
4
two numbers are equal
Nested if
if( cond 1)
{
/* Executes boolean expression when cond 1 is true */
if(cond 2) {
/* Executes when the boolean expression 2 is true */
}
}
Example:
#include <stdio.h>
int main ()
{
int a = 100;
int b = 200;
if( a == 100 )
/* if condition is true then check the following */
{ if( b == 200 )
/* if condition is true then print the following */
{
printf("Value of a is 100 and b is 200\n" );
}
}
printf("Exact value of a is : %d\n", a );
printf("Exact value of b is : %d\n", b );
return 0;
}
if(test-condition-1) If(test-condition-1)
(stmts) if(test-condition-2)
else
statement-1;
if(condition 2)
else
Statement-1;
statement-2;
else
statement-2; else
statement-3;
statement-x statement-x
If the test-condition-1 is false, the statement-3 will be executed; other wise it continues
the second test. If the condition-2 is true, the statement-2 will be evaluated and then the
control is transferred to the statement-x.
Example:Program to relate two integers using =, > or <
#include <stdio.h>
int main()
{
int number1, number2;
printf("Enter two integers: ");
scanf("%d %d", &number1,
&number2);
}
return 0;
}
The switch statement:
When many conditions are to be checked then using nested if...else is very difficult, confusing and
cumbersome.So C has another useful built in decision making statement known as switch.
This statement can be used as multiway decision statement.The switch statement tests the
value of a given variable or expression against a list of case values and when a match is
found, a block of statements associated with that case is executed.
Eg-1
int i = 1; switch( code)
switch(i) {
{ case 1:
case 1: stmts1;
printf("A"); break;
break;
case 2:
case stmts2;
2: printf("B");
break;
break;
case 3:
stmts3
case printf("C");
break;
3: break;
default: default:
} stmtsx
Example2: C program to find largest of umber }
#twinoclnude<stdio.h>
void main () For case 1,da=10% of basic
{ salary. For case 2, da=15% of
float basic , da , basic salary. For case 3,
salary ; int code
da=20% of basic salary.
;
char name[25]; For default case >3 da is not
printf("Enter employee name\
n"); scanf("%[^\n]",name); o/p
printf("Enter basic salary\n");
scanf("%f",&basic); Enter name of employee:
printf("Enter code of the Kartiyani
Enter Basic
Employee\n"); scanf("%d",&code); salary 5000
switch (code)
{ Enter code of
case 1: employee 1
da = basic * 0.10;
break; Employee name
case 2: is Kartiyani
da = basic * 0.15; DA is 500 and total salary is 5500
break;
case 3:
da = basic * 0.20;
break; default :
da = 0;
}
salary = basic + da;
printf("Employee name
is\n"); printf("%s\
n",name);
printf ("DA is %f and Total salary is =%f\n",da,
salary); getch();
}
Rules for using switch statement
BREAK is a keyword that allows us to jump out of a loop instantly, without waiting to
get back to the conditional test.
break;
tput
Example program value of a: 10
#include <stdio.h> value of a: 11
int main () value of a: 12
{ value of a: 13
int a = 10; while( a < value of a: 14
20 ) value of a: 15
{
printf("value of a: %d\n", a);
a++;
if( a > 15)
{
break;
}
}
return 0;
}
Continue
The continue statement in C programming works somewhat like the break statement.
Instead of forcing termination, it forces the next iteration of the loop to take place,
skipping any code in between.
For the for loop, continue statement causes the conditional test and increment portions
of the loop to execute. For the while and do...while loops, continue statement causes the
program control to pass to the conditional tests.
Syntax: continue;
GOTO
GOTO STATEMENT
„C‟ supports goto statement to branch unconditionally from one point to another in the
program.
Syntax
goto label;
..
.
label: statement;
Or
label: statement;
...
...
goto label;
Output
value of a: 10
value of a: 11
value of a: 12
Example program value of a: 13
#include value of a: 14
<stdio.h> value of a: 16
int main () value of a: 17
{ value of a: 18
int a = 10; value of a: 19
ABCL:do
{
if( a == 15)
{
a = a + 1;
goto ABCL;
}
printf("value of a: %d\n", ;
a++; a)
}while( a < 20 )
return 0;
}
program to print „n‟ natural number
#include<stdio.h>
void main( )
{
int n,i=1;
clrscr();
printf("enter number");
scanf("%d\t",n);
printf("natural numbers from 1 to %d", n);
lb: printf("%d\t",i);
i++;
if(i<=n)
goto lb;
getch();
}
LOOPING STATEMENTS
Types of Loop
1. while loop
2. for loop
3. do while loop
while loop
statements;
Example-- Example: //Program to print first 10 natural numbers
#include<stdio.h
> void main( )
{
int
x; x
= 1;
while(x <= 10)
{
printf("%d\t",
x); x++;
}
}
Output: 1 2 3 4 5 6 7 8 9 10
do while loop
5 10 15 20 25 30 35 40 45 50 55 60
Jumping Out of Loops
1) break statement
For Loop
4.MULTIDIMENTIONAL ARRAYS
Array Declaration:
To declare an array in C, a programmer specifies the type of the elements and
the number of elements required. The arraySize must be an integer constant
greater than zero and datatype can be any valid C data type.
Example-1
int n=25; int n;
int number[20]; double x[n], y[n]; //array Scanf(“%d”,&n);//get
int marks[44]; declaratio
float salary[10]; size int x[n]; //array
double n declaration
value[25]; int main( )
{
#include<stdio.h int N=10,M=20;
>#define N
100 int main(
)
{
int int marks[N*M];//array dec
marks[N];//array ....
dec return 0;
.... }
return 0;
}
Syntax-2
<storage class> datatype arrayName[ arraySize ];
mark[0] = 55
mark[1] = 66
mark[2] = 77
mark[3] = 88
mark[4] = 99
it means.
balance[0] = 1000.0;
balance[1] = 2.0;
balance[2] = 3.4;
balance[3] = 7.0;
balance[4] = 50.0;
Automatic sizing
int arr[] = {3,1,5,7,9};
Here, the C compiler will deduce the size of the array automatically based on the number of
OPERATIONS ON ARRAYS
o Traversing an array
o Inserting an element in an array
o Searching an element in an array
o Deleting an element from an array
o Merging two arrays
o Sorting an array in ascending or descending order
Working with one dimensional array
STORE and DISPLAY VALUES IN AN ARRAY (traversing an
array) #include<stdio.h>
int main( ) Output:
{ Enter the array elements
int k,array[10];//array declaration 2
printf(―Enter the array elements:‖);
for(k=0;k<5;k++)
{
scanf(―%d ‖,&array[i]); // storing values in array
} Display the array elements
printf(―\n Display the array 2
elements:‖); for(k=0;k<5;k++)
{
printf(―%d \n‖,array[i]);//displaying values of array
}
return 0;
}
FIND SUM AND AVERAGE OF N NUMBERS
#include<stdio.h>
int main( Output:
Enter the array size: 6
){
Enter the array elements
int k,n,sum=0;array[10];//array 9
declaration float avg;
printf(―\n Enter the array
size:‖); scanf(―%d‖,&n);
printf(―\n Enter the array
elements:‖); for(k=0;k<n;k++)
{
scanf(―%d ‖,&array[i]); // storing values in array sum=27 and avg=4.50000
}
for(k=0;k<n;k++)
{
sum=sum+array[i]; //sum of array elements
}
avg=sum/n;
printf(―\n sum=%d and avg=%f ‖,sum,avg);
}
return 0; Output:
} Enter the arrayelements
REVERSE OF ARRAY ELEMENTS 2
#include<stdio.h> 4
int main( ) 3
{ 1
int k,n,array[10];//array 8
declaration printf(―\n Enter the Display the arrayelements
8
array size:‖); scanf(―%d‖,&n);
1
printf(―\n Enter the array
3
elements:‖); for(k=0;k<n;k++)
4
2
{
scanf(―%d ‖,&array[i]); // storing values in array
}
printf(―\n array elements in reverse
order:‖); MM for(k=n-1;k>=0;k--)
{
printf(―%d \n‖,array[i]);//displaying values of array
}
return 0;
}
Write a program to print the position of the smallest number of n numbers using
arrays.
#include
<stdio.h> int
main()
{
int i, n, arr[20], small, pos;
printf("\n Enter the number of elements in the array :
"); scanf("%d", &n);
printf("\n Enter the elements
: "); for(i=0;i<n;i++)
scanf("%d",&arr[i]);
small = arr[0] Output
for(i=1;i<n;i+ Enter the number of elements in the
+) array : 5 Enter the elements : 7 6 5 14 3
{ if(arr[i]< The smallest element is : 3
small) The position of the smallest element in
{ the array is : 4
small =
arr[i]; pos =
i;
}
}
printf("\n The smallest element is : %d", small);
printf("\n The position of the smallest element in the array
is:
%d", pos);
return 0;
}
Logic Here the remainders of the integer division of a decimal number by 2 are
storedas consecutivearrayelements.Thedivisionprocedure is
repeateduntilthenumberbecomes 0.
Two dimentional arrays stores data in tabular column format represented as rows and
columns
Array Declaration:
datatype arrayname[size][size];
Array Initialization:
int a[2][2]={ {1,4 },{2,3}}
int b[2][2]={1,4,2,3}
1 4
2 3
12.3 45.2
19.3 23.4
1 2 3 4 5 6 7 8 9
Row 0 Row 1 Row 2
WORKING WITH TWO-DIMENSIONAL ARRAYS
Transpose of a matrix
Transpose of A is AT=(aji), where i is the row number and j is the column number.
Program
#include
<stdio.h> int
main()
{
int a[10][10], transpose[10][10], r, c, i, j;
printf("Enter rows and columns of matrix: ");
scanf("%d %d", &r, &c);
Sample output
// getting elements of the matrix Enter rows and columns of
printf("\nEnter elements of matrix:\ matrix: 2
n"); for(i=0; i<r; ++i) 3
for(j=0; j<c; ++j)
{ Enter element of matrix:
printf("Enter element a%d%d: ",i+1, j+1); Enter element a11: 2
scanf("%d", &a[i][j]); Enter element a12: 3
} Enter element a13: 4
Enter element a21: 5
// Displaying the matrix a[][] */ Enter element a22: 6
printf("\n Entered Matrix: \n"); Enter element a23: 4
for(i=0; i<r; ++i)
for(j=0; j<c; ++j) Entered Matrix:
{ 234
printf("%d ", a[i]
[j]); if (j == c-1) 564
printf("\n\n");
}
Transpose of Matrix:
// Finding the transpose of matrix 2 5
a for(i=0; i<r; ++i)
for(j=0; j<c; ++j) 3 6
{
transpose[j][i] = a[i][j]; 4 4
}
return 0;
}
Program -2(Transpose)
#include <stdio.h>
void main()
{
int array[10][10];
int i, j, m, n;
$ cc pgm85.c
$ a.out
Enter the order of the matrix
3 3
Enter the coefiicients of the
matrix 3 7 9
2 7 5
6 3 4
The given matrix is
3 7 9
2 7 5
6 3 4
Transpose of matrix is
3 2 6
7 7 3
9 5 4
Matrix addition and subtraction
#include <stdio.h>
int main(){
int r, c, a[100][100], b[100][100], sum[100][100], i, j;
#include
<stdio.h>
#include
<math.h> #defi
ne row 10 #defi
ne col 10 int
main()
{
fl oat mat[row][col],
s; int i,j,r,c;
printf(“\n Input number of
rows:”); scanf(“%d”, &r);
printf(“\n Input number of
cols:”); scanf(“%d”, &c);
for(i = 0 ; i< r; i++)
{
for(j = 0 ;j<c; j++)
{
scanf(“%f”, &mat[i][j]);
}
}
printf(“\n Entered 2D array is as
follows:\n”); for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf(“%f”, mat[i][j]);
}
printf(“\
n”);
}
s = 0.0;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
s += mat[i][j] * mat[i][j];
}
}
printf(“\n Norm of above matrix is: %f”,
sqrt(s)); return 0;
}
C Program to read a matrix and find sum, product of all elements of two dimensional (matrix)
array
include <stdio.h>
#define MAXROW Enter number of Rows :3
Enter number of Cols :3
10
#define MAXCOL 10 Enter matrix elements :
int main() Enter element [1,1] : 1
{ Enter element [1,2] : 1
int matrix[MAXROW][MAXCOL]; Enter element [1,3] : 1
int i,j,r,c; Enter element [2,1] : 2
int sum,product; Enter element [2,2] : 2
Enter element [2,3] : 2
printf("Enter number of Rows :");
Enter element [3,1] : 3
scanf("%d",&r);
printf("Enter number of Cols
Enter element [3,2] : 3
:"); scanf("%d",&c); Enter element [3,3] : 3
}
sum+=a[i][j];
}//for
printf("\nThe sum of diagonal elements is %d",sum); return 0;
}//main
#include <stdio.h>
void main ()
{ static int array[10] Enter the order of the matix
[10]; int i, j, m, n, a = 0, sum 22
= 0; Enter the co-efficients of the
printf("Enetr the order of the matix \n"); matrix 40 30
scanf("%d %d", &m, &n); 38 90
if (m == n ) The given matrix is
{ 40 30
printf("Enter the co-efficients of the matrix\n"); 38 90
for (i = 0; i < m; ++i)
{ The sum of the main diagonal elements is
for (j = 0; j < n; ++j) = 130
{ The sum of the off diagonal elements is
scanf("%d", &array[i][j]); = 68
}
}
printf("The given matrix is \
n"); for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
{
printf(" %d", array[i][j]);
}
printf("\n");
}
C Program to Find the Frequency of Odd & Even Numbers in the given Matrix
#include <stdio.h>
void main()
{
S. Functions
No
1 Functions
Introduction
Types of Function Implementation
Passing Arguments(Parameters) To
Function
Call by Value
Call by Reference
Recursive Functions
Example Programs using functions
2 Pointers
Introduction --Definition --Declaration
Pointer Arithmetic
Pointers and arrays
Pointers and Strings
Pointers and Functions
3 Structures
Intro
Declaration—Initialization --Accessing
Programs using structures
Structure within Structure[Nested
Structure]
Arrays and Structures
Structure and functions
Pointers and structure
4 Union
5 Union using Structure
6 Storage classes
7 Pre-processor directives.
FUNCTION
A function is self contained program segment that carries out some specific,well defined task.
Need For Functions:
Many programs require a set of instructions to be executed repeatedly from several places in a
program, then the repeated code can be placed within a single function, which can be accessed
whenever it is required.
Dividing the program into separate well-defined functions facilitates each function to be written
and tested separately.
Understanding, coding, and testing multiple separate functions is easier than doing the same for one
big function main function.
A big program is broken into comparatively smaller functions.
Advantages of Functions
-Improves readability of code.
-Divides a complex problem into simpler ones
- Improves reuseability of code.
-Debugging errors is easier.
-modifying a program is easier.
Terms
A function f that uses another function g is known as the calling function, and
g is known as the called function.
The inputs that a function takes are known as arguments.
When a called function returns some result back to the calling function, it is
said to return
that result.
The calling function may or may not function,which can theot pass
parameters to the called function.
Function Declaration
Function Definition
Function Call
Function Definition
When a function is defined, space is allocated for that function in the memory. A function
definition comprises of two parts:
Function header
Function body
The syntax of a function definition can be given as:
Syntax-1:
function_name(variable1, variable2, ...);
If the return type of the function is not void then the following syntax can be
used. Syntax-2
Function Declaration
It is also called as function prototype. A function prototype consists of 4 parts
(1) Return type
(2) function name
(3) parameter list
(4) terminating (;) semicolin
int a,b,c;
scanf(“%d%d”,&a,&b); // get input values for a and
b c=x+y;
printf(“c=%d”,c);
}
CASE-2 NOT PASSING ARGUMENTS & RETURNING SOME VALUE
#include <stdio.h>
int sum( ); //FUNCTION DECLARATION o/p
int main( ) 2
{ sum( ); //FUNCTION CALL 3
printf(“c=%d”,c); c=5
}
int sum( ) // FUNCTION DEFINITION
{
int a,b,c;
scanf(“%d%d”,&a,&b); // get input values for a and
b c=x+y;
return c;
}
CASE-3 PASSING ARGUMENTS & NOT RETURNING ANYTHING
#include <stdio.h>
int sum( int a,int b); //FUNCTION DECLARATION o/p
int main( ) 2
{ int a,b; 3
scanf(“%d%d”,&a,&b); // get input values for a and b c=5
sum(int a,int b ); //FUNCTION CALL
}
int sum( int x,int y) // FUNCTION DEFINITION
{
int c;
c=x+y
;
printf(“c=%d”,c);
}
CASE-4 NOT PASSING ARGUMENTS & RETURNING SOME VALUE
#include <stdio.h>
int sum( int a,int b); //FUNCTION DECLARATION o/p
int main( ) 2
{ int a,b,c; 3
scanf(“%d%d”,&a,&b); // get input values for a and c=5
b c=sum(int a,int b ); //FUNCTION CALL printf(“c=
%d”,c);
return 0;
}
int sum( int x,int y) // FUNCTION DEFINITION
{ int result
result=x+y;
return result;
}
PASSING ARGUMENTS(PARAMETERS) TO FUNCTION
Call by value
In Call by value, during function call actual parameter value is copied and
passed to formal parameter. Changes made to the formal parameters does not
affect the actual parameter.
Eg Program - C program to swap two numbers using call by value
#include<stdio.h
> int main()
{
int n1, n2;
printf("Enter two numbers:
"); scanf("%d%d", &n1,
&n2);
printf("In Main values before swapping: %d %d\n\n", n1,
n2); swap(n1, n2);
printf("In Main values after swapping: %d %d", n1,
n2); return 0;
}
void swap(int num1, int num2)
{
int temp;
printf("In Function values before swapping: %d %d\n", num1,
num2); temp = num1;
num1 =
num2; num2
= temp;
printf("In Function values after swapping: %d %d\n\n", num1, num2);
}
Output -
NOTE : In the above program swap() function does not alter actual parameter value. Before
passing the value of n1 and n2 to the swap() function, the C runtime copies the value of
actual parameter n1 and n2 to a temporary variable and passes copy of actual parameter.
Therefore inside the swap() function values has been swapped, however original value of n1
and n2 in main() function remains unchanged.
Call by reference
#include
<stdio.h> int
main()
{ int n1, n2;
printf("Enter two numbers:
"); scanf("%d%d", &n1,
&n2);
printf("In Main values before swapping: %d %d\n\n", n1,
n2); swap(&n1, &n2);
printf("In Main values after swapping: %d %d", n1,
n2); return 0;
}
void swap(int * num1, int * num2)
{
int temp;
printf("In Function values before swapping: %d %d\n", *num1,
*num2); temp = *num1;
*num1 = *num2;
*num2 = temp;
printf("In Function values after swapping: %d %d\n\n", *num1, *num2);
}
Output :-
Enter two numbers: 10 20
In Main values before swapping: 10 20
In Function values before swapping: 10
20 In Function values after swapping: 20
10 In Main values after swapping: 20 10
In above example instead of passing a copy of n1 and n2, to swap() function. Operations
performed on formal parameter is reflected to actual parameter (original value). Hence,
actual swapping is performed inside swap() as well as main() function.
WRITE THESE SWAP PROGRAM(S) FOR YOUR EXAMS
Call by value
#include<stdio.h>
Void swap(int x,int
y); int main( )
Before swapping x and y
{ 10 20
int a = 10, b = 20 ; After swapping x and y
swap (a,b) ; // calling by value 20 10
printf ( "\n Before swapping x and y)
; printf ( "\na = %d b = %d", a, b ) ;
return 0;
}
void swap( int x, int y)
{
int t ;
t=x;
x=y;
y=t;
printf ( "\n After swapping x and
y) ; printf( "\nx = %d y = %d",
*x,*y);
}
Call by reference
#include<stdio.h>
Void swap(int *x,int Before swapping x and y
10 20
*y); int main( ) After swapping x and y
{ 20 10
int a = 10, b = 20 ;
swap ( &a, &b ) ; // calling by
reference printf ( "\n Before swapping x
and y) ; printf ( "\na = %d b = %d", a, b )
;
return 0;
}
void swap( int *x, int *y )
{
int t ;
t = *x ;
*x = *y ;
*y = t ;
printf ( "\n After swapping x and
y) ; printf( "\nx = %d y = %d",
*x,*y);
}
Call by value Call by reference
When a function is called the actual values When a function is called the address
are passed of values(arguments) are passed
The parameters passed are normal variables The parameters passed are pointer variables
In call by value, actual arguments cannot be Modification to actual arguments is
modified. possible within from called function.
Actual arguments remain preserved and Actual arguments will not be preserved.
no chance of modification accidentally.
Calling Parameters: swap(a,b) Calling Parameters: swap(&a,&b)
Receiving parameters: void swap( int x, int y) Receiving parameters: void swap( int *x, int *y)
PASSING ARRAYS TO A FUNCTION
A function that calls itself is known as a recursive function. And, this technique is known
as recursion.
Advantage of Recursion
Disadvantage of Recursion
3*2 =6
2*1=2
1 * 1=1
Returns 1 as n value is 0
TOWER OF HANOI OF A NUMBER USING RECURSIVE FUNCTION
#include <stdio.h>
void hanoi(int n, char from, char to, char temp)
{
if (n == 1)
{
printf("\n Move Disk 1 from Peg %c to %c", from, to);
return;
}
hanoi(n-1, from, temp, to);
printf("\n Move disk %d from rod %c to rod %c", n, fr,
tr); hanoi(n-1, temp, to, from);
}
int main()
{
Printf(“ Towers of Honoi”);
int n;
printf(“\n Enter number of Disks”);
scanf(” %d ”,&n); // n implies the number of discs
hanoifun(n, 'A', 'C', 'B'); // A, B and C are the name of
Peg return 0;
}
To Transfer from disks from peg A to C taking help of B
Output
Move Disk 1 from Peg 1 to Peg 3.
Move Disk 2 from Peg 1 to Peg 2.
Move Disk 1 from Peg 3 to Peg 2.
Move Disk 3 from Peg 1 to Peg 3.
Move Disk 1 from Peg 2 to Peg 1.
Move Disk 2 from Peg 2 to Peg 3.
Move Disk 1 from Peg 1 to Peg 3.
Example: GCD of Two Numbers using Recursion
#include <stdio.h>
int hcf(int n1, int
n2); int main()
{
int n1, n2;
printf("Enter two positive integers:
"); scanf("%d %d", &n1, &n2);
STUDENTSFOCUS
Example: Fibonacci Series using Recursion
#include <stdio.h>
int fibonacci(int i)
{
if(i == 0)
{
return 0; Output
}
if(i == 1) 0
{
1
return 1; 1
}
2
return fibonacci(i-1) + fibonacci(i-2); 3
} 5
8
int main() 13
{
21
int i,f;
for (i = 0; i < 10; i++)
34
{
f= fibonacci(i);
printf("%d \n ",f);
}
return 0;
}
Pointers in C Programming
Note :Here %u is a format specifier. It stands for unsigned, so it will only display positive values.
&-address of operator.
& is the “address of” operator. It is used to tell the C compiler to refer to the address of variables.
Address of any variable can’t be negative. This is the reason %u format specifier is used to print
the address of variables on the screen.
This is the second operator used for pointers. It is used to access the value present at some
address. And it is used to declare a pointer.
int x=10;
int *ptr; // Declaration of Pointer variable
ptr=&x; // Storing address of x variable in y pointer variable
Example program-1
#include<stdio.h>
void main()
{ 6 12
int 65524 65522
65524 65522
a=6,b=12; 6 12
int *x,*y; 65524 65522
x=&a; 6 12
y=&b;
printf("%d t %d n",a,b);
printf("%u t %u n",&a,&b);
printf("%u t %u n",x,y);
printf("%d t %d n",*x,*y);
printf("%d t %d",(&a),
(&b));
printf("%d t %d",*(&a),*(&b));
}
#include <stdio.h>
int main ()
{
int var = 20; int *ip; /* actual variable declaration */
ip = &var; /* pointer variable declaration */
/* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var );
/*address stored in pointer variable*/ printf("Address stored in ip variable: %x\n",
/*access the value using the pointer */ printf("Value of *ip variable: %d\n", *ip );
return 0;
}
A pointer is a variable whose value is the memory address of another
variable
syntax
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-
name is the name of the pointer variable.
#include
<stdio.h> int
main ()
{
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr);
return 0;
}
output
The value of ptr is 0
Incrementing a Pointer(32-bit )
#include
<stdio.h> const
int MAX = 3; int
main () {int
var[] = {10,
100,
200};
int i, *ptr;
/* let us have array address in pointer */
ptr = var;
for ( i = 0; i < MAX; i++) {
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );
/* move to the next location */
ptr++;
}
return 0;
}
output
Address of var[0] =
bf882b30 Value of var[0]
= 10 Address of var[1] =
bf882b34 Value of var[1]
Decrementing a Pointer(32-bit machine)
decreases its value by the number of bytes of its data type.
#include
<stdio.h> const
int MAX = 3; int
main () {
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = &var[MAX-1];
for ( i = MAX; i > 0; i--) {
printf("Address of var[%d] = %x\n", i-1, ptr );
printf("Value of var[%d] = %d\n", i-1, *ptr );
/* move to the previous location */
ptr--;
}
return 0;
}
output
Address of var[2] =
bfedbcd8 Value of var[2]
= 200 Address of var[1] =
bfedbcd4 Value of var[1]
= 100 Address of var[0] =
bfedbcd0 Value of var[0]
printf("p1 = %d\n",
p1); printf("p2 = %d\
n", p2);
val = *p1+*p2;
printf("*p1+*p2 = %d\n", val);//point 1
p3 = p1-p2;
printf("p1 - p2 = %d\n", p3); //point 2
p1++;
printf("p1++ = %d\n", p1); //point 3
p2--;
printf("p2-- = %d\n", p2); //point 4
return 0;
}
OUTPUT
p1 = 2680016
p2 = 2680012
*p1=5;
*p2=10;
*p1+*p2 = 15
p1-p2 = 1
p1++ = 2680020
p2-- = 2680008
STRUCTURES
Structure is a user-defined data type that can store related information (of different
data types) together. The major difference between a structure and an array is that an array can
store only information of same data type. A structure is therefore a collection of variables under
a single name. The variables within a structure are of different data types.
A structure is a collection of variables under a single name. These variables can be
of different types, Therefore, a structure is a convenient way of grouping together
several pieces of related information.
Complex hierarchies can be created by nesting structures.
Declaration/Initializing/Accessing
Nesting of Structures
Arrays of Structures
Structures and Pointers
Structures and Functions
DECLARING STRUCTURES AND STRUCTURE VARIABLES
There are three different ways to declare and/or define a structure. These are
Variable structure
Tagged structure
Type-defined structure
1. A variable structure may be defined as follows.
struct
{
member_list
}variable_identifier
;
struct
{
where.....a,student1-are called as
int r_no;
structure variables
char name[20];
char course[20];
float fees;
} student1;
...
2.A tagged structure has been described earlier. It has the following format:
struct tag_name
{
member_list
}variable_identifier
;
struct student
{
int r_no;
char name[20];
char
course[20];
float fees; Memory allocation
} stud1, stud2;
typedef keyword enables the programmer to create a new data type name by using
an existing data type.
A structure can be initialized in the same way as other data types are initialized. Initializing a
structure means assigning some constants to the members of the structure.
struct struct_name
{
data_type
member_name1;
data_type
member_name2; data_type
member_name3;
.......................
}struct_var = {constant1, constant2,
constant3,...}; Example-1
struct student
{
int r_no;
char name[20];
char
course[20];
float fees;
}stud1 = {01, "Rahul", "BCA", 45000};
stud1.r_no Stud2.r_no
stud1.name Stud2.name
stud1.course Stud2.course
Each member of a structure can be used just like a normal variable, but its name will be a bit
longer. A structure member variabl e is generally accessed using a '.' (dot) operator.
stud1.r_no = 01;
stud1.name = "Rahul";
stud1.course =
"BCA"; stud1.fees =
45000;
To input values for data members of the structure variable stud1, we may write
scanf("%d",
&stud1.r_no); scanf("%s",
stud1.name);
printf("%s",
stud1.course);
printf("%f", stud1.fees);
Example-2 both initializing and accessing member data
struct {
float p,
q, int r;
} k = {k .p = 3.0, k.q = 7.9, k.r = 5};
Write a program using structures to read and display the information about a student
#include <stdio.h>
struct student
{
int roll_no;
char
name[80];
float fees;
char DOB[80];
};
int main()
{
struct student stud1;
Output
Enter the roll number : 01
Enter the name : Rahul
Enter the fees : 45000
Enter the DOB : 25–09–1991
********STUDENT‟S DETAILS
******* ROLL No. = 01
NAME = Rahul
FEES = 45000.00
DOB = 25–09–1991
C program to read and print employee's record using structure
#include <stdio.h>
struct employee
{
char
name[30];
int empId;
float salary;
};
int main()
{
struct employee emp; // declare structure
variable printf("\nEnter details :\n");
printf(“\n
************”);
printf("Name ?:");
scanf(“%s”,emp.name);
printf("ID ?:");
scanf("%d",&emp.empId);
printf("Salary ?:");
scanf("%f",&emp.salary);
Output
Enter details :
**********
Name ?:Mik
e ID ?:1120
Salary ?:76543
#include <stdio.h>
struct employee
{
char
grade; int
basic;
float allowance;
};
int main()
{
struct employee ramesh={„B‟, 6500, 812.5}; /* creating & initializing
member of employee */
Output:
vivek‟s grade is B
vivek‟s basic is Rs
6500 vivek‟s allowance
is Rs 812.500000
Using Typedef :- A program that prints the weight of various sizes of fruits.
#include <stdio.h>
typedef struct fruits
{
float big;
float
medium;
float small;
}fruits weight;
int main()
{
weight
apples={200.75,145.5,100.25};
weight pears={150.50,125,50};
weight mangoes={1000, 567.25, 360.25};
printf(“\n\n apples: big size %f kg, medium size %f kg, small size %f kg”, apples.big,
apples.medium, apples.small);
printf(“\n\n pears: big size %f kg, medium size %f kg,small size %f kg”, pears.big,
pears.medium, pears.small);
printf(“\n\n mangoes: big size %f kg, medium size %f kg,small size %f kg”, mangoes.big,
mangoes.medium, mangoes.small);
return 0;
}
Output:
apples: big 200.75kg, medium 145.50kg, small 100.25kg
pears: big 150.50kg, medium 125.00kg, small 50.00kg
mangoes: big 1000kg, medium 567.25kg, small
360.25kg
Nesting of Structures
A structure can be placed within another structure. In other words, structures can contain other
structures as members. A structure within a structure means nesting of structures.
In such cases, the dot operator in conjunction with the structure variables are used to access the
members of the innermost as well as the outermost structures.
struct student
{
int roll_no;
char
name[100];
float fees;
struct DOB date;
};
int main()
{
struct student stud1;
int main()
{
struct outer outvar; /* declaring structure_variable of outer */
outvar.out1= 2; /* assigning values to members
*/ outvar.out2= 10.57;
outvar.invar.in1= 2* outvar.out1; /* assigning values to members
*/ outvar.invar.in2= outvar.out2 + 3.65;
Output:
out1=2, out2= 10.57, in1=4, in2= 14.22
Write a program to read, display, add, and subtract two complex numbers.
#include <stdio.h>
#include <conio.h> Output
int main() ******** MAIN MENU *********
{ 1. Read the complex numbers
typedef struct complex 2. Display the complex numbers
{ 3. Add the complex numbers
int real; 4. Subtract the complex numbers
int imag; 5. EXIT
}COMPLEX;
COMPLEX c1, c2, sum_c, sub_c; Enter your option : 1
Enter the real and imaginary parts of the first complex
int number : 4 5
Enter the real and imaginary parts of the second complex
option; do number : 2 3
{ Enter your option : 2
printf("\n ******** MAIN MENU *********"); The first complex numbers is : 4+5i
printf("\n 1. Read the complex numbers"); The second complex numbers is :
printf("\n 2. Display the complex numbers"); 2+3i Enter your option : 3
printf("\n 3. Add the complex numbers"); printf("\ The sum of two complex numbers is : 6+8i
n 4. Subtract the complex numbers"); printf("\n 5. Enter your option : 4
EXIT"); The difference between two complex numbers is : 2+2i
printf("\n Enter your option :
Enter your option : 5
"); scanf("%d", &option);
switch(option)
{
case 1:
printf("\n Enter the real and imaginary parts of the first complex number : ");
scanf("%d %d", &c1.real, &c1.imag);
printf("\n Enter the real and imaginary parts of the second complex number : ");
scanf("%d %d", &c2.real, &c2.imag);
break;
case 2:
printf("\n The first complex number is : %d+%di", c1.real,c1.imag);
printf("\n The second complex number is : %d+%di",
c2.real,c2.imag); break;
case 3:
sum_c.real = c1.real + c2.real;
sum_c.imag = c1.imag +
c2.imag;
printf("\n The sum of two complex numbers is : %d+%di",sum_c.real, sum_c.imag);
break;
case 4:
sub_c.real = c1.real – c2.real;
sub_c.imag = c1.imag –
c2.imag;
printf("\n The difference between two complex
numbers is :%d+%di", sub_c.real, sub_c.imag);
break;
}
}while(option != 5);
return 0;
}
ARRAYS OF STRUCTURES
Arrays of structures means that the structure variable would be an array of objects, each of which contains
the member elements declared within the structure construct.
struct student
Syntax {
struct struct_name int r_no;
{ char name[20];
data_type char
member_name1;
data_type course[20];
member_name2; float fees;
data_type };
member_name3; A student array can be declared by writing,
....................... struct student stud[30];
Now, to assign values to the ith student of the class, we can write as
stud[i].r_no = 09;
stud[i].name =
"RASHI";
stud[i].course =
"MCA"; stud[i].fees
= 60000;
int main()
{
int i;
struct boat ticket[4][3]={{“Vikram”,1,15.50},{“Krishna”,2,15.50},
{“Ramu”,3,25.50},{“Gouri”,4, 25.50 } };
printf(“\n passenger Ticket num.
Fare”);
for(i=0;i<=3;i++)
printf(“\n %s %d %f ”, ticket[i].name,ticket[i].seatnum,ticket[i].fare);
return 0;
}
Output:
Passenger Ticket num. Fare
Vikram 1 15.500000
Krishna 2 15.500000
Ramu 3 25.500000
Gouri 4 25.500000
C program to generate salary slip of employees using structures
#include<stdio.h>
struct emp
{
int empno ;
char name[10] ;
int bpay, allow, ded, npay ;
} e[10] ;
void main()
{
int i, n ;
Enter the employee number: 2001 Enter the employee number: Bina
Enter the basic pay, allowances & deductions: 80000 10000 3000
Emp.No.Name NetSalary
**************************** 1001Rina83000
2001Bina87000
Write a program to read and display the information of all the students in a class. Then
edit the details of the ith student and redisplay the entire information.
#include <stdio.h>
#include
<string.h> struct
student
{
int roll_no;
char
name[80]; int
fees;
char DOB[80];
};
int main()
{
struct student stud[50];
int n, i, num, new_rollno;
int new_fees;
char new_DOB[80],
new_name[80]; clrscr(); // clear
screen
printf("\n Enter the number of students :
"); scanf("%d", &n);
for(i=0;i<n;i++)
{
printf("\n Enter the roll number :
"); scanf("%d", &stud[i].roll_no);
for(i=0;i<n;i++)
{
printf("\n ********DETAILS OF STUDENT %d*******",
i+1); printf("\n ROLL No. = %d", stud[i].roll_no);
printf("\n NAME = %s",
stud[i].name); printf("\n FEES = %d",
stud[i].fees); printf("\n DOB = %s",
stud[i].DOB);
}
printf("\n Enter the student number whose record has to be edited : ");
scanf("%d", &num);
stud[num].roll_no = new_rollno;
strcpy(stud[num].name,
new_name); stud[num].fees =
new_fees;
strcpy (stud[num].DOB, new_DOB);
for(i=0;i<n;i++)
{
printf("\n ********DETAILS OF STUDENT %d*******",
i+1); printf("\n ROLL No. = %d", stud[i].roll_no);
printf("\n NAME = %s",
stud[i].name); printf("\n FEES = %d",
stud[i].fees); printf("\n DOB = %s",
stud[i].DOB);
}
getch();
return 0;
} Output
Enter the number of students :
2 Enter the roll number : 1
Enter the name : kirti
Enter the fees : 5678
Enter the DOB : 9- 9-
99
#include
<stdio.h> typedef
struct
{
int
x; int
y;
}POINT;
int main()
{
POINT p1 = {2, 3}; Output
display(p1.x, p1.y); // function call The coordinates of the point are: 2 3
return 0;
}
#include
<stdio.h> typedef
struct
{
int
x; int
y;
}POINT;
void display(POINT);
int main()
{
POINT p1 = {2, 3};
display(p1)
; return 0;
}
void display(POINT p)
{
printf("The coordinates of the point are: %d %d", p.x, p.y);
}
Passing Structure by Value
In this approach, the structure object is passed as function argument to the definition of
function, here object is reperesenting the members of structure with their values.
Program
#include<stdio.h>
struct Employee
{
int Id;
char
Name[25]; int
Age;
long Salary;
};
void main()
{
struct Employee Emp =
{1,"Kumar",29,45000}; Display(Emp);
Output
:
Employee Id : 1
Employee Name :
Kumar Employee Age :
29 Employee Salary :
45000
Passing Structure by Reference
Program
#include<stdio.h>
struct Employee
{
int Id;
char
Name[25]; int
Age;
long Salary;
};
void Display(struct
Employee*); void main()
{
struct Employee Emp =
{1,"Kumar",29,45000}; Display(&Emp);
Output
:
Employee Id : 1
Employee Name :
Kumar Employee Age :
29 Employee Salary :
45000
Passing Structures through Pointers
struct struct_name
{
data_type
member_name1;
data_type
member_name2;
data_type
member_name3;
.......................
}*ptr;
or,
struct struct_name *ptr;
The next thing to do is to assign the address of stud to the pointer using the address
operator (&).
ptr_stud = &stud;
(*ptr_stud).roll_no;
#include <stdio.h>
struct student
{
int r_no;
char name[20];
char
course[20]; int
fees;
};
int main()
{
struct student stud1,
*ptr_stud1; ptr_stud1 =
&stud1;
Storage class of a variable defines the lifetime and visibility of a variable. Lifetime means
the duration till which the variable remains active and visibility defines in which module of
the program the variable is accessible. They are:
1. Automatic
2. External
3. Static
4. Register
This variable is visible only within the function it is declared and its lifetime is same as the
lifetime of the function as well. This is the default storage class we have been using so far. It
applies to local variables only and the variable is visible only inside the function in which it is
declared and it dies as soon as the function execution is over. If not initialized, variables of
class auto contains garbage value.
The value is lost after the execution of
function. Syntax: auto datatype var_name1 [= value];
Example:
int var; // by default, storage class is auto
auto int var; // auto int j=10;
Example Program:
#include<stdio.h>
void
display();
void main()
{
auto int a=10; //OR int
a=10; printf("\n A1 : %d",a);
display();
printf("\n A3 : %d",a);
}
void display()
{
int a=20; //OR auto int
a=20; printf("\n A2 : %d",a);
}
Output :
A1 : 10
A2 : 20
A3 : 10
2. External Storage Class
External storage class reference to a global variable declared outside the given program.
extern keyword is used to declare external variables. They are visible throughout the
program and its lifetime is same as the lifetime of the program where it is declared. This
visible to all the functions present in the program.
Example Program:
#include<stdio.h>
void display();
extern int a=10; //global
variable void main()
{
printf("\nA :
%d",a); increment();
display(); printf("\
nA : %d",a);
}
void increment()
{
a = 20;
}
void display()
{
printf("\nA : %d",a);
}
Output :
A : 10
A : 20
A : 20
3. Static Storage Class
Static storage class ensures a variable has the visibility mode of a local variable but
lifetime of an external variable. It can be used only within the function where it is declared
but destroyed only after the program execution has finished. The default initial value of static
variable is 0. The value of a static variable persists between function calls
.
Syntax: static datatype var_name1 [= value];
Example: static int x = 101;
static float sum;
During multiple calling static variables retains their previous value.
#include<stdio.h
> void
display(); void Output:
main()
{ A:1
display() A:2
; A:3
display()
;
display()
;
}
void display()
{
static int a=1;
printf("\nA :
%d",a); a++;
}
In the above example, we does not use static keyword then the output will be :
Output : A : 1
A : 1
A : 1
4. Register Storage Class
Variables of class 'register' are stored in CPU registers instead of memory which
allows faster access. It has its lifetime and visibility same as automatic variable. The scope of
the variable is local to the function in which it is defined and it dies as soon as the function
execution is over. It contains some garbage value if not initialized. The purpose of creating
register variable is to increase access speed and makes program run faster. As register space
is very limited, so only those variables which requires fast access should be made register It
is declared as:
C Program
Preprocessor
Compiler
Linker
Executable
Code
Fig. 2.8 Working Procedure of C Program
There are four types of Preprocessor Directives supported by C language. They are:
File Inclusion directive
Macro Substitution directive
Conditional directive
Miscellaneous directive
List of all possible directives belong to each of the above is listed in Fig 2.9.
#include
It is used to include header file inside C Program. It checks for header file in current
directory, if path is not mentioned. To include user defined header file double quote is used
("") instead of using triangular bracket (< >).
Example:
#include <stdio.h> // Standard Header
File #include "big.h" // User Defined Header File
Preprocessor replaces #include <stdio.h> with the content of stdio.h header file.
#include "Sample.h" instructs the preprocessor to get Sample.h from the current directory
and add the content of Sample.h file.
Macro Substitution
directive #define
It is a simple substitution macro. It substitutes all occurrences of the constant and
replace them with an expression.There are two types of macro supported by C. They are:
1. Simple macro
2. macro with arguments
Simple
macro
Syntax:
#define identifier value
Wher
e #define - is apreprocessor directive used for text substitution.
identifier - is an identifier used in program which will be replaced by value.
(In general the identifiers are represented in captital letters in order
to differentiate them from variable)
value -It is the value to be substituted for identifier.
Example:
#define PI 3.14
#define NULL 0
Example:
//Program to find the area of a circle using simple macro
#include <stdio.h>
#define PI
3.14 int main()
{
int
radius;
float
area;
printf(“Enter the radius of circle \
n”); scanf(“%d”, &radius);
area= PI * radius * radius;
printf(“Area of Circle=%f”,
radius);
}
Output
Enter the radius of
circle 10
Area of Circle = 314.000000
macro with arguments
#define Preprocessing directive can be used to write macro definitions with
parameters. Whenever a macro identifier is encountered, the arguments are substituted by the
actual arguments from the C program.
Data type definition is not necessary for macro arguments. Any numeric values like
int, float etc can be passed as a macro argument . Specifically, argument macro is not case
sensitive.
Example:
#define area(r) (3.14*r*r)
Example:
//Program to find the area of a circle using macro with arguments
#include <stdio.h>
#define area(r)
(3.14*r*r) int main()
{
int
radius;
float a;
printf(“Enter the radius of circle \
n”); scanf(“%d”, &radius);
a= area(radius);
printf(“Area of Circle=%f”, a);
}
Output
Enter the radius of
circle 10
Area of Circle = 314.000000
C Programming language defines a number of macros. Table 2.8 is the list of some
commonly used macros in C
Table 2.8 Predefined macros in C
Macro Description
NULL Value of a null pointer constant.
EXIT_SUCCESS Value for the exit function to return in case of successful
completion of program.
EXIT_FAILURE Value for the exit function to return in case of program
termination due to failure.
RAND_MAX Maximum value returned by the rand function.
FILE Contains the current filename as a string.
LINE Contains the current line number as a integer constant.
DATE Contains current date in "MMM DD YYYY" format.
TIME Contains current time in "HH:MM:SS" format.
Example:
NULL : 0
EXIT_SUCCESS : 0
EXIT_FAILURE : 1
RAND_MAX : 32767
File Name :
BuiltinMacro.c DATE :
Aug 16 2017
Line : 12
Conditional directive
The Conditional directives permit to include a block of code based on the result of
conditional expression.
Syntax:
#if <expression>
statements;
#elif
<expression>
statements;
#else
statements;
#endif
Wher
e
Expression represents a condition which produces a boolean value as a result.
Conditional directive is similar to if else condition but it is executed before
compilation. Condition_Expression must be only constant expression.
Example:
#undef
Syntax:
#undef <Constant>
Example:
#include<stdio.h
> #define P 100
#ifdef P
#undef P
#define P 30
#else
#define P 100
#endi
f
int main()
{
printf("%d",P);
return 0;
}
Output
30
#ifdef #ifdef,
#ifndef #ifdef
#ifdef directive is used to check whether the identifier is currently defined.
Identifiers can be defined by a #define directive or on the command line.
#ifndef
#ifndef directive is used to check whether the identifier is not currently defined.
Example:
#ifdef PI
printf( "Defined \n" );
#endif
#ifndef
PI
printf( "First define PI\n" );
#endi
f Output:
First define PI
Miscellaneous
directive STUDENTSFOCUS
The pragma directive is used to access compiler-specific preprocessor
extensions. Each pragma directive has different implementation rule and use . There
are many type of pragma directive and varies from one compiler to another compiler .If
compiler does not recognize particular pragma then it ignores the pragma statement
without showing any error or warning message.
Example:
#pragma
sample int
main()
{
printf(“Pragma verification
“); return 0;
}
Output
Pragma verification
Since #pragma sample is unknown for Turbo c compiler, it ignores sample
directive without showing error or warning message and execute the whole program
assuming #pragma sample statement is not present. The following are the list of
possible #pragma directives supported by C.
1. #pragma startup
2. #pragma exit
3. pragma warn
4. #pragma option
5. #pragma inline
6. #pragma argsused
7. #pragma hdrfile
8. #pragma hdrstop
9. #pragma saveregs
#error
The #error directive causes the preprocessor to emit an error message. #error
directive is used to prevent compilation if a known condition that would cause the
program not to function properly.
Syntax:
#error “message”
Example
: int
main()
{
#ifndef PI
#error "Include
PI” #endif
}
return 0; STUDENTSFOCUS
Output
compiler error --> Error directive : Include PI
#line
It tells the compiler that next line of source code is at the line number which has
been specified by constant in #line directive
Syntax:
#line <line number> [File
Name] Where Output
File Name is optional 700
Example: 701
int main() 702
{
#line 700
printf(Line Number %d”, LINE );
printf(Line Number %d”, LINE );
printf(Line Number %d”, LINE );
return 0;
}
Unit III– Linear Structures-List
UNIT III LINEAR DATA STRUCTURES
Arrays and its representations – Stacks and Queues – Linked lists – Linked list-based implementation
of Stacks and Queues – Evaluation of Expressions – Linked list based polynomial addition.
INTRODUCTION
Definition
Data structure is a particular way of organizing, storing and retrieving data, so that it can be used efficiently. It is the
structural representation of logical relationships between elements of data.
Primitive Data Structure - Primitive data structures are predefined types of data, which are supported by the
programming language. These are the basic data structures and are directly operated upon by the machine
instructions, which is in a primitive level.
Non-Primitive Data Structure - Non-primitive data structures are not defined by the programming language, but are
instead created by the programmer. It is a more sophisticated data structure emphasizing on structuring of a group
of homogeneous (same type) or heterogeneous (different type) data items.
Linear data structure- only two elements are adjacent to each other. (Each node/element has a single successor)
o Restricted list (Addition and deletion of data are restricted to the ends of the list)
Stack (addition and deletion at top end)
Queue (addition at rear end and deletion from front end)
o General list (Data can be inserted or deleted anywhere in the list: at the beginning, in the middle or at the end)
Non-linear data structure- One element can be connected to more than two adjacent elements.(Each node/element
can have more than one successor)
o Tree (Each node could have multiple successors but just one predecessor)
o Graph (Each node may have multiple successors as well as multiple predecessors)
Note - Array and Linked list are the two basic structures for implementing all other ADTs.
1
Unit III– Linear Structures-
List
MODULARITY
Module- A module is a self-contained component of a larger software system.Each module is a logical unit and
does a specific job. Its size kept small by calling other modules.
Modularity is the degree to which a system's components may be separated and recombined. Modularity refers to
breaking down software into different parts called modules.
Advantages of modularity
o It is easier to debug small routines than large routines.
o Modules are easy to modify and to maintain.
o Modules can be tested independently.
o Modularity provides reusability.
o It is easier for several people to work on a modular program simultaneously.
2
Unit III– Linear Structures-
o Code is easier to understand. Provides modularity and reusability. List
o Implementations of ADTs can be changed without requiring changes to the program that uses the ADTs.
LIST ADT
List is a linear collection of ordered elements.The general form of the list of size N is: A0, A1, …, AN-1
o Where A1 - First element
AN - Last element
N - Size of the
list
o If the element at position 'i' is Ai then its successor is Ai+1 and its predecessor is Ai-1.
Various operations performed on a List ADT
o Insert (X,5) - Insert the element X after the position 5.
o Delete (X) - The element X is deleted.
o Find (X) - Returns the position of X
o Next (i) - Returns the position of its successor element i+1.
o Previous (i) - Returns the position of its Predecessor element i-1.
o PrintList - Displays the List contents.
o MakeEmpty - Makes the List empty.
Find Routine
void Find (int X)
{
int i,f=0;
for(i=0;i<N;i++)
if(a[i]==x)
{ f=
1;
break;
}
if (f==1)
printf(“Element found”);
else
printf(“Element not found”);
}
Unit III– Linear Structures-
List
STACK
Definition
Stack is alinear list in which elements are added and removed from only one end, called the top.It is a "last in,
first out" (LIFO) data structure. At the logical level, a stack is an ordered group ofhomogeneous items or
elements.Because items are added and removed only from the top of the stack, the last element to be added is the first
to be removed. Stacks are also referred as "piles" and "push-down lists".
Operations on stacks
Push - Inserts new item to the top of the stack. After the push, the new item becomes the top.
Pop - Deletes top item from the stack. The next older item in the stack becomes the top.
Top - Returns a copy of the top item on the stack, but does not delete it.
MakeEmpty - Sets stack to an empty state.
Boolean IsEmpty - Determines whether the stack is empty. IsEmpty should compare top with -1.
Boolean IsFull - Determines whether the stack is full. IsFull should compare top with MAX_ITEMS - 1.
Conditions
Stack overflow - The condition resulting from trying to push an element onto a full stack.
Stack underflow - The condition resulting from trying to pop an element from an empty stack.
APPLICATIONS OF STACKS
Recursion - Example, Factorial, Tower of Hanoi.
Balancing Symbols, i.e., finding the unmatched/missing parenthesis. For example, ((A+B)/C and (A+B)/C).
Compilers often use stacks to perform syntax analysis of language statements.
Conversion of infix expression to postfix expression and decimal number to binary number.
Evaluation of postfix expression.
Backtracking- For example, 8-Queens problem.
Function calls - When a call is made to a new function, all the variables local to the calling routine need to be saved
by the system, since otherwise the new function will overwrite the calling routine's variables. Similarly the current
location in the routine must be saved so that the new function knows where to go after it is done. For example, the
main program calls operation A, which in turn calls operation B, which in turn calls operation C. When C finishes,
control returns to B; when B finishes, control returns to A; and so on. The call-and-return sequence is essentially a
LIFO sequence, so a stack is the perfect structure for tracking it.
Implementations of stack
1. Array implementation of stack
2. Linked list implementation of stack
void push();
void pop();
void display();
int stack[MAX], top=-1, item;
void push()
{
if(top == MAX-1)
printf("Stack is full");
else
{
printf("Enter item: ");
scanf("%d",&item);
top++;
stack[top] = item;
printf("Item pushed = %d", item);
}
}
void pop()
{
if(top == -1)
printf("Stack is empty");
else
{
item = stack[top];
top--;
printf("Item popped = %d", item);
}
}
void display()
{
int i;
if(top == -1)
printf("Stack is empty");
else
{
for(i=top; i>=0; i--)
printf("\n %d", stack[i]);
}
}
Unit III– Linear Structures-
List
Types of Queues
There are three major variations in a simple queue. They are
Linear queue
Circular queue
Double ended queue (Deque)
o Input restricted deque
o Output restricted deque
Priority queue
Operations on Queue
Enqueue -Insertsan itemat the rear end of the queue.
Dequeue- Deletesan item at the front end of the queue and returns.
Conditions
Queue overflow - The condition resulting from trying to enqueue an element onto a full Queue.
Queue underflow - The condition resulting from trying to dequeue an element from an empty Queue.
Implementation of Queue
1. Array implementation
2. Linked list implementation
o Array and linked list implementations give fast O(1) running times for every operation
0 1 2 3 4
Empty Queue F = R = -1
10
0 1 2 3 4
^^
Unit III– Linear Structures-
FR List
10 3
0 1 2 3 4
^ ^
F R
After Enqueue (3)
10 3 41
0 1 2 3 4
^ ^
F R
After Enqueue (41)
3 41
0 1 2 3 4
^ ^
F R
After Dequeue ()
3 41 76
0 1 2 3 4
^ ^
F R
After Enqueue (76)
3 41 76 66
0 1 2 3 4
^ ^
F R
After Enqueue (66)
41 76 66
0 1 2 3 4
^ ^
F R
After Dequeue ()
There is one potential problem with array implementation. From the above queue, now if we attempt to add more
elements, even though 2 queue cells are free, the elements cannot be inserted. Because in a queue, elements are
Unit III– Linear Structures-
Listqueue array Q[4]. That is queue is full
always inserted at the rear end and hence rear points to last location of the
(overflow condition) though it is empty.
The simple solution is that whenever front or rear gets to the end of the array, it is wrapped around to the
beginning. This is known as a circular array implementation.
Array implementation of Linear Queue
#include <stdio.h>
#include<conio.h>
#define MAX 3
void enqueue();
void dequeue();
void display();
void enqueue()
{
if(rear == MAX-1)
printf("Queue is full");
else
{
printf("Enter item :
"); scanf("%d",
&item);
if (rear == -1 && front == -
1) rear = front = 0;
else
rear = rear + 1;
queue[rear] = item;
printf("Item enqueued : %d", item);
}
}
void dequeue()
{
if(front == -1)
printf("Queue is empty");
else
{
item = queue[front];
if (front == rear)
front = rear = -1;
else
front = front + 1;
int i;
}
}
void display()
{
Unit III– Linear Structures-
List
printf("Item dequeu ed : %d", item);
if(front == -1)
Unit III– Linear Structures-
List
printf("Queue is empty");
else
for(i=front; i<=rear; i++)
printf("%d ", queue[i]);
}
Circular Queue
In circular queues the elements Q[0],Q[1],Q[2].......Q[n – 1] is represented in a circularfashion with Q[1] following
Q[n]. A circularqueue is one in which the insertion of a newelementis done at the very first location of the queue if
the last location at the queue isfull.
Initially Front = Rear = -1. That is, front and rear are at the same position.
At any time the position of the element to be inserted will be calculated by therelation: Rear = (Rear + 1) % SIZE
After deleting an element from circular queue the position of the front end is calculatedby the relation: Front=
(Front + 1) % SIZE.
After locating the position of the new element to be inserted, rear, compare it withfront. If Rear = Front, the queue
is full and cannot be inserted anymore.
No of elements in a queue = (Rear – Front + 1) % N
Deque - Double Ended QUEeue
Definition
A deque is a homogeneous list in which inserted and deleted operations are performed at either ends of the
queue. That is, we can add a new element at the rear or front end and also we can remove an element from both front
and rear end. Hence it is called double ended queue. The most common ways of representing deque are: doubly linked
list, circular list.
Types of deques
1. Input restricted deque
2. Output restricted deque
An input restricted deque is a deque, which allows insertion at only 1 end, rear end, but allows deletion at
both ends, rear and front end of the lists.
An output-restricted deque is a deque, which allows deletion at only one end, front end, but allows insertion at
both ends, rear and front ends, of the lists.
Unit III– Linear Structures-
List
Priority Queue
Definition
Priority Queue is a queue where each element is assigned a priority. The priority may implicit (decided by its value)
or explicit (assigned). In priority queue, the elements are deleted and processed by following rules.
o An element of higher priority is processed before any element of lower priority.
o Two elements with the same priority are processed according to the order in which they were inserted
to the queue.
Example for priority queue:
o In a telephone answering system, calls are answered in the order in which they are received;
o Hospital emergency rooms see patients in priority queue order; the patient with the most severe injuries
sees the doctor first.
A node in the priority queue will contain Data, Priority and Next field. Data field will store the actual information;
Priority field will store its corresponding priority of the data and Next will store the address of the next node.
When an element is inserted into the priority queue, it will check the priority of the element with the element(s)
present in the linked list to find the suitable position to insert. The node will be inserted in such a way that the data
in the priority field(s) is in ascending order. We do not use rear pointer when it is implemented using linked list,
because the new nodes are not always inserted at the rear end.
Applications of queue
When jobs are submitted to a printer, they are arranged in order of arrival. Thus, essentially, jobs sent to a line
printer are placed on a queue.
Virtually every real-life line is (supposed to be) a queue. For instance, lines at ticket counters are queues, because
service is first-come first-served.
Another example concerns computer networks. There are many network setups of personal computers in which the
disk is attached to one machine, known as the file server. Users on other machines are given access to files on a first-
come first-served basis, so the data structure is a queue.
Calls to large companies are generally placed on a queue when all operators are busy.
There are several algorithms that use queues to solve problems easily. For example, BFS, Binary tree traversal etc.
Round robin techniques for processor scheduling is implemented using queue.
LINKED LIST
Definition
Linked list is adynamic data structure which is an ordered collection of homogeneous dataelements called nodes, in which each
12
Unit III– Linear Structures-
List
Why Linked List?
Even though searching an array for an individual element can be very efficient, array has some limitations. So
arrays are generally not used to implement Lists.
SentinelNode
It is also called as Header nodeor Dummy node.
Advantages
o Sentinel node is used to solve the following problems
First, there is no really obvious way to insert at the front of the list from the definitions given.
Second, deleting from the front of the list is a special case, because it changes the start of the list; careless
coding will lose the list.
A third problem concerns deletion in general. Although the pointer moves above are simple, the deletion
algorithm requires us to keep track of the cell before the one that we want to delete.
Disadvantages
o It consumes extra space.
Insertion
a. Creating a newnode from empty List
Deletion
a. Inserting a node to the front of list
Find Routine
/* Returns the position of X in L; NULL if not found */
Position Find (int X)
{
position p;
P = head->next;
while( (p!= NULL) && (p->data != X)
) p = p->next;
return P;
}
FindPrevious Routine
/* Returns the previous position of X in L */
Unit III– Linear Structures-
List
position FindPrevio (int X)
{
position
P;
P = head;
while( (P->Next!= NULL) && (P->Next->data != X) )
P = P->Next;
return P;
}
FindNext Routine
/* Returns the position of X in L; NULL if not found */
Position Find (int X)
{
position p;
P = head->next;
while( (p!= NULL) && (p->data != X)
) p = p->next;
return P->next;
}
void traversal ()
{
position p;
P = head->next;
while( p!= NULL)
{
printf(p->data);
p = p->next;
}
}
Insertion
Inserting a node to the front of list
Insert at Beginning
void Insert_beg (int X)
{
position NewNode;
NewNode = malloc (sizeof(struct Node));
Unit III– Linear Structures-
if(NewNode != NULL) List
{
NewNode->data = X;
NewNode->next = L->Next;
head->next = NewNode;
}
}
Insertion at Middle
/* Insert element X after position P
*/ void Insert_mid (int X, position P)
{
position NewNode;
NewNode = malloc (sizeof(struct Node));
if(NeWNode != NULL)
{
NewNode->data = X;
NewNode->next = P->next;
P->next = NewNode;
}
}
c.Inserting a node to the end of list
Insert at Last
void Insert_last (int X)
{
position NewNode,P;
NewNode = malloc (sizeof(struct Node));
if(NewNode != NULL)
{
while(P->next!=NULL)
P = P->next;
NewNode->data = X;
NewNode->next = NULL;
P->next = NewNode;
}
18
Unit III– Linear Structures-
} List
Deletion
Deleting a node to the front of list
Delete at Beginning
void Delete_beg ()
{
position TempCell;
if(head->next!=NULL)
{
TempCell = head->next;
head->next = TempCell ->next;
free(TempCell);
}
Deleting the middle node
Delete at Last
void Delete_last ()
{
position TempCell,P;
while(P->next->next!=NULL)
Unit III– Linear Structures-
P = P->next; List
TempCell = P->next;
P->next = NULL;
free(TempCell);
}
Disadvantages
The circular linked list requires extra care to detect the end of the list. It may be possible to get into an infinite loop.
So it needs a header node to indicate the start or end of the list.
Definition
A circular linked list is one, which has no beginning and no end. Circular linked list is a list in which every node has a
successor; the "last" element is succeeded by the "first" element. We can start at any node in the list and traverse
the entire list.
Advantages
Traversing in reverse is possible.
Deletion operation is easier, since it has pointers to its predecessor and successor.
Unit III– Linear Structures-
Finding the predecessor and successor of a node is easier. List
Disadvantages
A doubly linked list needs more operations while inserting or deleting and it needs more space (to store the extra
pointer). There are more pointers to keep track of in a doubly linked list. For example, to insert a new node after a
given node, in a singly linked list, we need to change two pointers. The same operation on a doubly linked list
requires four pointer changes.
Definition
A circular linked list is one, which has no beginning and no end. A doubly circular linked list is a doubly linked list with
circular structure in which the last node points to the first node and the first node points to the last node and there are
two links between the nodes of the linked list. In doubly circular linked list, the left link of the leftmost node contains the
address of the rightmost node and the right link of the rightmost node contains the address of the leftmost node.
Push operation
Pop operation
struct node
{
int data;
struct node *next;
} *top = NULL;
}
}
Unit III– Linear Structures-List
void pop()
{
position p;
p = top->next;
if (top == NULL)
printf("Stack is
empty");
else
{
top->next= top->next->next;
printf("\n Popped value : %d\n", p-
>data); free(p);
}
}
void display()
{
struct node
*p; if (top ==
NULL)
printf("Stack is empty");
else
{
p = top;
while(p != NULL)
{
printf("\n%d", p-
>data); p = p->next;
}
Linked list implementation of Linear Queue
Unit III– Linear Structures-
Linked liswr Queue List
struct node
{
int data;
struct node *next;
} *front = NULL, *rear=NULL;
position;
struct node
{
int data;
struct node *next;
} *top = NULL;
void dequeue()
{
position p;
p = front->next;
if (front == NULL)
printf("Queue is empty\
n");
else
{
printf("\n Dequeued value : %d\n", p-
>data); front->next=front->next->next;
free(p);
}
void display()
{
position p;
p = front->next;
if (front == NULL)
printf("Queue is empty\
n");
else
{
printf("Queue elements are : \n");
while (p != NULL)
Unit III– Linear Structures-
{ List
www.Vidyarthiplus.com
24
Unit III– Linear Structures-
List
printf("%d ",p->data);
p = p->next;
}
}
APPLICATIONS OF STACKS
Recursion - Example, Factorial, Tower of Hanoi.
Balancing Symbols, i.e., finding the unmatched/missing parenthesis. For example, ((A+B)/C and (A+B)/C).
Compilers often use stacks to perform syntax analysis of language statements.
Conversion of infix expression to postfix expression and decimal number to binary number.
Evaluation of postfix expression.
Backtracking- For example, 8-Queens problem.
Function calls - When a call is made to a new function, all the variables local to the calling routine need to be saved
by the system, since otherwise the new function will overwrite the calling routine's variables. Similarly the current
location in the routine must be saved so that the new function knows where to go after it is done. For example, the
main program calls operation A, which in turn calls operation B, which in turn calls operation C. When C finishes,
control returns to B; when B finishes, control returns to A; and so on. The call-and-return sequence is essentially a
LIFO sequence, so a stack is the perfect structure for tracking it.
Operator precedence
( Highest
^ -
*, / -
+, - Least
25
Unit III– Linear Structures-
List
26
Unit III– Linear Structures-
List
Balancing parenthesis
One common programming problem is unmatched parenthesis in an algebraic expression. When parentheses are
unmatched, two types of errors can occur:
o Opening parenthesis can be missing. For example, [A+B]/C}.
o Closing parenthesis can be missing. For example, {(A+B)/C.
The steps involved in checking the validity of an arithmetic expression
1. Scan the arithmetic expression from left to right.
2. If an opening parenthesis is encountered, push it onto the stack.
3. If a closing parenthesis is encountered, the stack is examined.
a. If the stack is empty, the closing parenthesis does not have an opening parenthesis. So the expression is
invalid.
b. If the stack is not empty, pop from the stack and check whether the popped item corresponds to the
closing parenthesis. If a match occurs, continue. Otherwise, the expression is invalid.
4. When the end of the expression is reached, the stack must be empty; otherwise one or more opening parenthesis
does not have corresponding closing parenthesis. So the expression is invalid.
27
Unit III– Linear Structures-
List
Polynomial ADT
Polynomials are expressions containing terms with non-zero coefficients and exponents. Linked list is generally used to
represent and manipulate single variable polynomials. Different operations, such as addition, subtraction, division and
multiplication of polynomials can be performed using linked list. In this representation, each term/element is referred as
a node. Each node contains three fields namely,
1. Coefficient - Holds value of the coefficient of a term.
2. Exponent - Holds exponent value of a term.
3. Link - Holds the address of the next term.
For example,
28
Unit III– Linear Structures-
List
Multi-list
Multi-list is the most complicated applications of linked list. It is useful to maintain student registration in a
university, employee involvement in different projects etc. The student registration contains two reports. The first
report lists the registration for each class (C) and the second report lists, by student, the classes that each student (S) is
registered for. In this implementation, we have combined two lists into one. All lists use a header and are circular.
Circular list saves space but does so at the expense of time.
Polynomial Addition
Type Declaration:
struct node
{
int coeff;
int pow;
struct node *next;
}*poly1=NULL,*poly2=NULL,*poly=NULL;
29
Unit III– Linear Structures-
{ List
poly->coeff=poly1->coeff; poly1=poly1->next;
poly->pow=poly1->pow;
else if(poly1->pow<poly2->pow)
{
poly->pow=poly2->pow;
poly->coeff=poly2-
>coeff; poly2=poly2-
>next;
}
else
{
poly->pow=poly1->pow;
poly->coeff=poly1->coeff+poly2-
>coeff; poly1=poly1->next;
poly2=poly2->next;
}
poly->next=(struct node *)malloc(sizeof(struct
node)); poly=poly->next;
poly->next=NULL;
}
while(poly1->next !=NULL)
{
poly->pow=poly1->pow;
poly->coeff=poly1-
>coeff; poly1=poly1-
>next;
}
while(poly2->next!=NULL)
{
poly->pow=poly2->pow;
poly->coeff=poly2-
>coeff; poly2=poly2-
>next;
}
}
PART A
1. Why do we need ADT for implementing data structures? Or Benefits of ADT.
Code is easier to understand.
Provides modularity and reusability.
Implementations of ADTs can be changed without requiring changes to the program that uses the ADTs.
2. What is an ADT? What are all concerned and not concerned in an ADT? Give example.
ADT is a mathematical specification of the data, a list of operations that can be carried out on that data. It includes
the specification of what it does, but excludes the specification of how it does. Operations on set ADT: Union,
Intersection, Size and Complement.
Examples of ADT: Stack, Queue, List, Trees, Heap, Graph, etc.
30
Unit III– Linear Structures-
Queue (addition at rear end and deletion from front end) List
o General list (Data can be inserted or deleted anywhere in the list: at the beginning, in the middle or at the end)
Non-linear data structure- One element can be connected to more than two adjacent elements.(Each node/element
can have more than one successor)
o Tree (Each node could have multiple successors but just one predecessor)
o Graph (Each node may have multiple successors as well as multiple predecessors)
6. What is the advantage linked list over arrays?. Mention their relative advantages and disadvantages?
Advantages of Array
o Searching an array for an individual element can be very efficient,
Advantages of Linked List
o Linked list are dynamic data structures - The size is not fixed. They can grow or shrink during the execution of a
program.
o Efficient memory utilization - memory is not pre-allocated. Memory is allocated, whenever it is required and it
is de-allocated whenever it is not needed. Data are stored in non-continuous memory blocks.
o Insertion and deletion of elements are easier and efficient. Provides flexibility. No need to shift elements of a
linked list to make room for a new element or to delete an element.
Disadvantages of Linked List
o More memory - Needs space for pointer (link field).
o Accessing arbitrary element is time consuming. Only sequential search is supported not binary search.
7. What are the advantages of doubly linked list over singly linked list?
In singly linked list, it is difficult to perform traversing the list in reverse. To delete a node, we need find its
predecessor of that node.
9. What are the two important features present in a pointer implementation of linked list?
The two important features present in a pointer implementation of linked list are as follows
31
Unit III– Linear Structures-
The data are stored in a collection of structures. Each structure contains data and a pointer to the next
List
structure.
1. A new structure contains data from the system’s global memory by a call to malloc and released by a call to free.
11. What are the conditions that followed in the array implementation of stack?
Stack overflow - The condition resulting from trying to push an element onto a full stack.
Stack underflow - The condition resulting from trying to pop an element from an empty stack.
32
Unit III– Linear Structures-List
PART B
1. Explain the array and linked list implementation of stack.
2. Explain the array and linked list implementation of queue.
3. Explain how stack is applied for evaluating an arithmetic expression.
4. Explain the applications of stack, queue and linked list.
5. Explain polynomial addition using Linked list.
33
34
UNIT IV
NON-LINEAR DATA STRUCTURES
Syllabus:
Trees – Binary Trees – Binary tree representation and traversals –Binary Search Trees – Applications of
trees. Set representations – Union-Find operations. Graph and its representations – Graph Traversals.
TREES STRUCTURE
Definition:
Tree is a non-linear data structure. It organized the data in hierarchical manner. A tree is a finite set of one
or more nodes such that there is a specially designated node called the root node and root node can have zero
or more sub trees T1,T2,T3,...............,Tn. Each of whose roots are connected by a directed edge from root R.
Tree is collection of nodes in which the first node is called root and root has many number of sub tree T1,
T2, T3… Tn.
Terms:
1. Root
A node which does not have a parent is called as root node.
2. Node
Each data element in the tree is called as node.
3. Leaf node
A node which does not have any children is called leaf node.
4. Siblings
A child of same parent is called sibling.
5. Path
A path from node n1 to nk is defined has sequence of nodes n1, n2, n3........nk. Such that ni is a parent
of ni +1.Example: A->B->E->J
6. Length for a path
Number of edges in the path.
Example: Consider path from A to J is 3
7. Degree
Number of sub trees of the node is called degree.
8. Level
Root is at level 1 then i+s children are at level 2+1
Example: level
9. Depth
1
For any node n, the depth n is lengthwowf wun.Viqiudeyapraththipflruosm.ot to n.
10. Height
For any node n, the height of node n is the length of longest path from n to left.
11. Forest
Collection of tree node is known as forest.
Definition: -
Binary Tree is a special type of tree in which no node can have most two children. Typically, child
nodes of a binary tree on the left is called left child and node on right is called right child. Maximum number
of nodes
at level i of a binary tree is 2i-1.
A simple binary tree of size 9 and height 3, with a root node whose value is 2. The above tree is
neither a sorted nor a balanced binary tree
Representation of tree.
1. Sequential representation or array representation.
2. Linked representation.
1. Sequential representation or array representation.
The elements are represented using arrays. For any element in position i, the left child is in position 2i,
the right child is in position (2i + 1), and the parent is in position (i/2).
A B C D E F G
0 1 2 3 4 5 6
2. Linked representation
2
The elements are represented using pointers. Each node in linked representation has three fields, namely,
* Pointer to the left subtree
* Data field
* Pointer to the right subtree
Inorder Traversal
The inorder traversal of a binary tree is performed as
* Traverse the left subtree in inorder
* Visit the root
* Traverse the right subtree in inorder.
Recursive Routine for Inorder
Traversal void Inorder (Tree T)
{
if (T!=NULL)
{
Inorder (T->left);
printf(“%d”,T->data);
Inorder (T->right);
}
}
Preorder Traversal
3
The preorder traversal of a binary tree is perwfowrmw.eVdidays afortlhloipwlus,s.
* Visit the root
* Traverse the left subtree in preorder
* Traverse the right subtree in preorder.
Postorder Traversal
The postorder traversal of a binary tree is performed by the following steps.
* Traverse the left subtree in postorder.
* Traverse the right subtree in postorder.
* Visit the root.
Recursive Routine for Postorder Traversal
void Postorder (Tree T)
{
if (T ! = NULL)
{
Postorder (T ->Left);
Postorder (T -
>Right);
printf(“%d”,T->data);
}
EXPRESSION TREE
An expression tree is tree in which left nodes have the operands and interior node have the operators.
Like binary tree, expression tree can also be travesed by inorder, preorder and postorder traversal.
Example:
(A+B)*(C-D)
+ -
A B C D
Constructing an Expression Tree
Let us consider postfix expression given as an input for constructing an expression tree by performing the
4
following steps:
5
1. Read one symbol at a time from the postwfiwx wex.Vpriedsysaiortnhiapnludst.hcoemn scan the
expression from left to right manner.
2. Check whether the symbol is an operand or operator.
a. If the symbol is an operand, create a one - node tree and push a pointer on to the stack.
b. If the symbol is an operator pop two pointers from the stack namely T1 and T2 and form a new
tree with root as the operator and T2 as a left child and T1 as a right child. A pointer to this new
tree is then pushed onto the stack.
3. Repeated the above steps until reach the end of the expression.
4. The final pointer in the stack is complete expression
tree. Example:
ABC*+DE*F+G*+
Operations of BST.
1. Insertion
2. Deletion
3. Find
4. Find min
5. Find max
6. Retrieve
Notes: when you’re constructing the binary tree the given elements are read from first.
Example:
6
struct treenode
{
int data;
struct treenode *left;
struct treenode
*right;
};
Routine for perform find.
8
}
9
DIFFERENCE BETWEEN BINARY AND BINARwY
wSEwA.RVCidHyTaRrtEhEipSl:us.com
BINARY TREE BINARY SEARCH TREE
It is a tree with only two
It is also a tree with only two children.
children
It has no restrictions regarding In this the left child is lesser than the parent and the right
its children child is greater than the parent
11
12
Graphs
Introduction to graphs
A graph is a data structure that is used to represent a relational data e.g. a set of terminal in network
or roadmap of all cities in a country. Such complex relationship can be represented using graph data
structure. A graph is a structure made of two components, a set of vertex V and the set of edges E.
Therefore, a graph is G= (V, E) where G is graph. The graph may be directed or undirected. Vertices are
referred to as nodes and the arc between the nodes are referred to as Edges.
3. Connected graph
A graph is called connected if there is a path from any vertex to any other vertex.
Strongly Connected Graph If there is a path from every vertex to every other vertex in a directed graph
then it is said to be strongly connected graph. Otherwise, it is said to be weakly connected graph.
4. Multiple edges
5. Distinct edges e and e` are called multiple edges if they connected the same and point.
13
Ex: e=(U,V) then e`=(U,V)
6. Loop
An edges e is called loop if it has identical and points.
E=(U,U)
7. Path
A path is a sequence of distinct vertices, each adjacent to the next. The length of such a path is number of
edges on that path.
8. Cycle
A path from a node to itself is called cycle. Thus, a cycle is a path in which the initial and final vertices are
same.
Acyclic Graph A directed graph which has no cycles is referred to as acyclic graph. It is abbreviated as DAG
[Directed Acyclic Graph]
Note: a graph need not be a tree but a tree must be graph
9. Degree, incidence and adjacent
A vertex V is incident to an edges e if V is one of the two vertices in the order pair of vertices that
constitute e.
The degree of a vertex is the number of edges incident to it.
The indegree of vertex V is the number of edges that have V as head and the outdegree of vertex V is
number of edges that have v as the tail.
A vertex V is adjacent to vertex U if there is an edge from U to V. if V is adjacent to U,V is called a
successor of U, and U a predecessor of V.
10. Weighted graph
A weighted graph is a graph in which edges are assigned weighted. Weights of an edge are called as cost.
11. complete graph
If there is an edges from each vertices to all other vertices in graph is called as completed graph.
Graph and its representations
Graph is a data structure that consists of following two components:
1. A finite set of vertices also called as nodes.
2. A finite set of ordered pair of the form (u, v) called as edge. The pair is ordered because (u, v) is not same as (v, u)
in case of directed graph(di-graph). The pair of form (u, v) indicates that there is an edge from vertex u to vertex v.
The edges may contain weight/value/cost.
Graphs are used to represent many real life applications: Graphs are used to represent networks. The networks
may include paths in a city or telephone network or circuit network. Graphs are also used in social networks like
linkedIn, facebook. For example, in facebook, each person is represented with a vertex (or node). Each node is a
structure and contains information like person id, name, gender and locale. See this for more applications of graph.
Following is an example undirected graph with 5 vertices.
14
slot adj[i][j] = 1 indicates that there is an edge frwowmwve.Vrtiedxyiatrothvieprltuesx.cj.oAmdjacency matrix for
undirected graph is always symmetric. Adjacency Matrix is also used to represent weighted graphs. If adj[i][j] = w, then
there is an edge from vertex i to vertex j with weight w.
The adjacency matrix for the above example graph is:
Pros: Representation is easier to implement and follow. Removing an edge takes O(1) time. Queries like whether there
is an edge from vertex ‘u’ to vertex ‘v’ are efficient and can be done O(1).
Cons: Consumes more space O(V^2). Even if the graph is sparse(contains less number of edges), it consumes the same
space. Adding a vertex is O(V^2) time.
Adjacency List:
An array of linked lists is used. Size of the array is equal to number of vertices. Let the array be array[]. An entry array[i]
represents the linked list of vertices adjacent to the ith vertex. This representation can also be used to represent a
weighted graph. The weights of edges can be stored in nodes of linked lists. Following is adjacency list representation
of the above graph.
STUDENTSFOCUS
Adjacency List Representation of the above Graph
www.Vidyarthiplus.com
15
As in the example given above, BFS algorithm traverses from A to B to E to F first then to C and G lastly to D. It
employs the following rules.
Rule 1 − Visit the adjacent unvisited vertex. Mark it as visited. Display it. Insert it in a queue.
Rule 2 − If no adjacent vertex is found, remove the first vertex from the queue.
Rule 3 − Repeat Rule 1 and Rule 2 until the queue is empty.
www.Vidyarthiplus.com
17
6. Now, S is left with no unvisited adjacent nodes.
So, we dequeue and find A.
At this stage, we are left with no unmarked (unvisited) nodes. But as per the algorithm we keep on
dequeuing in order to get all unvisited nodes. When the queue gets emptied, the program is over.
As in the example given above, DFS algorithm traverses from A to B to C to D first then to E, then to F and
lastly to G. It employs the following rules.
www.Vidyarthiplus.com
18
Rule 1 − Visit the adjacent unvisited vwewrtwex.V. Midayrakrtiht iapsluvsis.citoemd. Display it. Push it in
a stack.
Rule 2 − If no adjacent vertex is found, pop up a vertex from the stack. (It will pop up all the
vertices from the stack, which do not have adjacent vertices.)
Rule 3 − Repeat Rule 1 and Rule 2 until the stack is empty.
www.Vidyarthiplus.com
19
Visit D and mark it as visited and put onto
the stack. Here, we have B and C nodes,
which are
4. adjacent to D and both are unvisited. However,
we shall again choose in an alphabetical order.
As C does not have any unvisited adjacent node so we keep popping the stack until we find a node that has an
unvisited adjacent node. In this case, there's none and we keep popping until the stack is empty.
www.Vidyarthiplus.com
20
UNIT V
Unit v
SEARCHING and SORTING ALGORITHMS
Syllabus
Linear Search – Binary Search. Bubble Sort, Insertion sort – Merge sort – Quick sort – Hash tables – Overflow
handling.
SEARCHING
Linear Search
Binary Search
Linear Search
A linear search scans one item at a time, without jumping to any item.
#include<stdio.h>
int main()
{
int a[20],n,x,i,flag=0;
printf("How many elements?");
scanf(“%d”,&n);
printf("\nEnter elements of the array\n");
for(i=0;i<n; i++)
scanf(“%d”,&a*i+); printf("\
nEnter element to search:");
scanf(“%d”,&x);
for(i=0;i<n;i++)
{
if(a[i]==x)
{
flag=1;
break;
}
}
if(flag)
printf("\nElement is found at position %d ",i+1);
else
printf("\nElement not found");
return 0;
}
The worst case complexity is O(n), sometimes known an O(n) search
Time taken to search elements keep increasing as the number of elements are increased.
Binary Search
A binary search however, cut down your search to half as soon as you find middle of a sorted list.
The middle element is looked to check if it is greater than or less than the value to be searched.Accordingly,
search is done to either half of the given list
www.Vidyarthiplus.com
1
UNIT V
#include<stdio.h>
int main()
{
int n,i,a[100],f=0,l,h;
printf("Enter the no. of
Elements:"); scanf(“%d”,&n);
printf("\nEnter Elements of Array in Ascending order\n");
for(i=0;i<n;++i)
{
scanf(“%d”,&a*i+);
}
printf("\nEnter element to
search:"); scanf(“%d”,&e);
l=0;
h=n-1;
while(l<=h)
{
m=(l+h)/2;
if(e==a[m])
{
f=1;
break;
}
else
if(e>a[m])
l=m+1;
else
h=m-1;
}
if(f==1)
cout<<"\nElement found at position "<<m+1;
else
cout<<"\nElement is not found ... !!!";
return 0;
}
Differences
Input data needs to be sorted in Binary Search and not in Linear Search
Linear search does the sequential access whereas Binary search access data randomly.
Time complexity of linear search -O(n) , Binary search has time complexity O(log n).
Linear search performs equality comparisons and Binary search performs ordering comparisons
www.Vidyarthiplus.com
2
UNIT V
SORTING
Sorting is linear ordering of list of items. Different types of sorting are
1. Bubble Sort
2. Insertion sort
3. Merge sort
4. Quick sort
Bubble Sort is a simple algorithm which is used to sort a given set of n elements provided in form of an
array with n number of elements. Bubble Sort compares all the element one by one and sort them based on
their values.
If the given array has to be sorted in ascending order, then bubble sort will start by comparing the first
element of the array with the second element, if the first element is greater than the second element, it
will swap both the elements, and then move on to compare the second and the third element, and so on. This
process will be repeated for n-1 times.(n- total elements)
It is known as bubble sort, because with every complete iteration the largest element in the given
array, bubbles up towards the last place or the highest index, just like a water bubble rises up to the water
surface.
Sorting takes place by stepping through all the elements one-by-one and comparing it with the
adjacent element and swapping them if required.
Bubble Sort:
#include <stdio.h>
void bubbleSort(int arr[], int n)
{
int i, j, temp;
for(i = 0; i < n; i++)
{
STUDENTSFOCUS
for(j = 0; j < n-i-1; j++)
{
if( arr[j] > arr[j+1])
{
// swap the
elements temp =
arr[j];
arr[j] = arr[j+1];
arr[j+1] =
temp;
}
}
}
4
UNIT V
}
}
int main()
{
int arr[100], i, n, step, temp;
printf("Enter the number of elements to be sorted: ");
scanf("%d", &n);
for(i = 0; i < n; i++)
{
printf("Enter elements\n");
scanf("%d", &arr[i]);
}
// call the function
bubbleSort bubbleSort(arr,
n);
return 0;
}
Example: Let's consider an array with values {5, 1, 6, 2, 4, 3}
STUDENTSFOCUS
As shown above, after the first iteration, 6 is placed at the last index, which is the correct position for it.
Similarly after the second iteration, 5 will be at the second last index, and so on.
5
UNIT V
wwINwSE.VRiTdIyOaNrtShOipRluTsIN.cGm
1. It is a simple Sorting algorithm which sorts the array by shifting elements one by one. Following
are some of the important characteristics of Insertion Sort.
2. It has one of the simplest implementation
3. It is efficient for smaller data sets, but very inefficient for larger lists.
4. Insertion Sort is adaptive, that means it reduces its total number of steps if given a partially sorted
list, hence it increases its efficiency.
5. It is better than Selection Sort and Bubble Sort algorithms.
6. Its space complexity is less, like Bubble Sorting, insertion sort also requires a single additional
memory space.
7. It is Stable, as it does not change the relative order of elements with equal keys
How Insertion Sorting Works
STUDENTSFOCUS
6
UNIT V
Complexity Analysis of Insertion
Sorting Worst Case Time Complexity :
O(n2) Best Case Time Complexity : O(n)
Average Time Complexity : O(n2)
Space Complexity : O(1)
Quick Sort, as the name suggests, sorts any list very quickly. Quick sort is not stable search, but it is very fast
and requires very less aditional space. It is based on the rule of Divide and Conquer(also called partition-
exchange sort). This algorithm divides the list into three main parts :
In the list of elements, mentioned in below example, we have taken 25 as pivot. So after the first pass, the list
will be changed like this.
6 8 17 14 25 63 37 52
Hence after the first pass, pivot will be set at its position, with all the elements smaller to it on its left and all
the elements larger than it on the right. Now 6 8 17 14 and 63 37 52 are considered as two separate lists,
and same logic is applied on them, and we keep doing this until the complete list is sorted.
7
UNIT V
{
pivot=left;
i=left+1;
j=right;
while(i<j)
{
while(arr[i]<=arr[pivot] &&
i<right) i++;
while(arr[j]>arr[pivot])
j--;
if(i<j)
{
tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
tmp=arr[pivot];
arr[pivot]=arr[j];
arr[j]=tmp;
qsort(arr,left,j-1);
qsort(arr,j+1,right);
}
}
Space required by quick sort is very less, only O(n log n) additional space is required.
Quick sort is not a stable sorting technique, so it might change the occurence of two similar elements
in the list while sorting.
Merge Sort follows the rule of Divide and Conquer. But it doesn't divides the list into two halves. In merge
sort the unsorted list is divided into N sublists, each having one element, because a list of one element is
considered sorted. Then, it repeatedly merge these sublists, to produce new sorted sublists, and at lasts one
sorted list is produced.
Merge Sort is quite fast, and has a time complexity of O(n log n). It is also a stable sort, which means the
"equal" elements are ordered in the same order in the sorted list.
8
UNIT V
Like we can see in the above example, merge sort first breaks the unsorted list into sorted sublists, and then
keep merging these sublists, to finlly get the complete sorted list.
#include<stdio.h>
#include<conio.h>
void merge(int [],int ,int ,int
); void part(int [],int ,int );
int main()
{
int arr[30];
int i,size;
printf("\n\t------- Merge sorting method--------\n\n");
printf("Enter total no. of elements : ");
scanf("%d",&size);
for(i=0; i<size; i++)
{
printf("Enter %d element :
",i+1); scanf("%d",&arr[i]);
}
part(arr,0,size-1);
printf("\n\t------- Merge sorted elements--------\n\n");
for(i=0; i<size; i++)
printf("%d ",arr[i]);
getch();
9
UNIT V
return 0;
}
Time complexity of Merge Sort is O(n Log n) in all 3 cases (worst, average and best) as merge sort always
divides the array in two halves and take linear time to merge two halves.It requires equal amount of
additional space as the unsorted list. Hence its not at all recommended for searching large unsorted lists.It is
the best Sorting technique for sorting Linked Lists.
10
UNIT V
HASHING
Hashing
Hashing is a process which uses a function to get the key and using the key it quickly identifies the
record, without much strain. The values returned by a hash function are called hash values. Hash table is data
structure in which key values are place in array location
Hash Table
The hash table data structure is an array of some fixed size, containing the keys. A key is a value associated
with each record.
A hash function, h, is a function which transforms a key from a set, K, into an index in a table of size n:
h: K -> {0, 1, ..., n-2, n-1}
• A key can be a number, a string, a record etc.The size of the set of keys, |K|, to be relatively very large.
It is possible for different keys to hash to the same array location.This situation are called collision and
the colliding keys are called synonyms.
•
A good hash function should:
· Minimize collisions.
· Be easy and quick to compute.
· Distribute key values evenly in the hash table.
· Use all the information provided in the key.
1 Truncation Method
The Truncation Method truncates a part of the given keys, depending upon the size of the hash table.
1. Choose the hash table size.
2. Then the respective right most or left most digits are truncated and used as hash code|
value. Ex: 123,42,56 Table size = 9
H(123)=1
H(42)=4
H(56)=5
www.Vidyarthiplus.com
11
UNIT V
ww0w.Vi yarthiplus.com
d
1 123
2
3
4 42
5 56
6
7
8
9
2 Mid square Method :
It is a Hash Function method.
1. Square the given keys.
2. Take the respective middle digits from each squared value and use that as the hash value | address | index
| code, for the respective keys.
H(123)=1 [ 1232 = 15129] 0
2
H(42)=7 [ 42 = 17 64 ] 1 123
H(56)=3 [ 562 = 3136 ] 2
3 56
4
5
6
7 42
8
9
3 Folding Method:
Partition the key K into number of parts, like K1,K2,.....Kn, then add the parts together and ignore the
carry and use it as the hash value.
H(123)= [ 1+2+3 =6 ]
0
H(43)= [ 4+3 = 7 ]
1 56
H(56)= [ 5+6 = 11 ]
2
3
4
5
6 123
7 43
4 Division Method :
Choose a number m, larger than the number of keys. The number m is usually chosen to be a prime number.
The formula for the division method :
Hash(key)= key % tablesize
Tablesize : 10 20,21,24,26,32,34
H(20)= 20 % 10 = 0
H(21)= 21 % 10 = 1
H(24)=24 % 10 = 4 www.Vidyarthiplus.com
12
UNIT V
H(26)= 26 % 10 = 6 www.Vidyarthiplus.com
H(32) = 32 % 10 = 2
H(34)=34%10=4 34 IS
COLLISION
0 20
1 21
2 32
3
4 24
5
6 26
7 42
8
9
Applications
• Database systems: Specifically, those that require efficient random access. Generally, database
systems try to optimize between two types of access methods: sequential and random. Hash tables
are an important part of efficient random access because they provide a way to locate data in a
constant amount of time.
• Symbol tables: The tables used by compilers to maintain information about symbols from a program.
Compilers access information about symbols frequently. Therefore, it is important that symbol tables
be implemented very efficiently.
• Data dictionaries: Data structures that support adding, deleting, and searching for data. Although
the operations of a hash table and a data dictionary are similar, other data structures may be used
to implement data dictionaries. Using a hash table is particularly efficient.
• Network processing algorithms: Hash tables are fundamental components of several network
processing algorithms and applications, including route lookup, packet classification, and
network monitoring.
• Browser Cashes: Hash tables are used to implement browser cashes.
HASH COLLISION:
A hash collision or hash clash is a situation that occurs when two distinct inputs into a hash function
produce identical outputs.
13
UNIT V
1 Separate Chaining
It is to keep a list of all elements that hash to the same value. An alternative to open addressing as a method
of collision resolution is separate chaining hashing. This uses an array as the primary hash table, except that
the array is an array of lists of entries, each list initially being empty.
If in a set of elements, if an element hashes to the same value as that of an already inserted element then
we have a collision and We need to resolve it. In separate chaining ,each slot of the bucket array is a pointer
to a linked list that contains key-value pairs that are hashed to the same location. It is otherwise called as
direct chaining or simply chaining. An array of linked list implementation is used here.
TO FIND AN ELEMENT
To perform a Find, we use the hash function to determine which list to traverse.
We then traverse it in normal manner, returning the position where the item is found.
Finding an element in separate chaining is very much similar to the find operation performed in
the case of lists.
If the ElementType is a string then a comparison and assignment must be done with strcmp and strcpy
respectively.
TO INSERT AN ELEMENT
To perform an Insert, we traverse down the appropriate list to check whether the element is already in
place .
If it is new then it is either inserted at the front or at the end.
If the item to be inserted is already present, then we do not perform any operation; otherwise we
place it at the front of the list. It is similar to the insertion Operation that takes place in the case of
linked lists.
The disadvantage is that it computes the hash function twice.
TO DELETE AN ELEMENT:
To delete we find the cell P prior to the one containing the element to be deleted.
14
UNIT V
Make the cell P to point to the next cwewll owf.Vthiedyealertmhiepnlut st.ocobme deleted.
Then free the memory space of the element to be deleted.
PROGRAM
HEADER FILE FOR SEPARATE CHAINING
Typedef int elementtype;
Typedef struct listnode *position;
Typedef struct hashtbl
*hashtable; Typedef position list;
Struct hashtbl
{
int tablesize;
list *thelists;
};
IMPLEMENTATION OF SEPARATE CHAINING
The Lists will be an array of
list. Struct listnode
{
Elementtype element;
Position next;
};
Hashtable initialize table(int tablesize)
{
Hashtable H;
int i;
/ *Allocate Table * /
H=malloc(sizeof(struct hashtable));
If(H==NULL)
Fatalerror(“Out of Space”);
H-->tablesize=nextprime(tablesize);
/*Allocate array of list */
H-->thelist=malloc(sizeof(list)*H-->tablesize);
If(H-->thelist==NULL)
Fatalerror(“Out of Space”);
/*Allocate list header */
For(i=0;i<H-->tablesize;i++)
{
H-->thelists[i]=malloc(sizeof(struct listnode));
If(H-->thelists[i]==NULL)
Fatalerror(“Out of
Space”);
Else
H-->thelists[i]-->next=NULL;
}
return H;
}
Hash(char *key, int tablesize)
{
int hashvalue=0;
15
UNIT V
while(*key!=’\0’)
hashvalue=hashvalue+ *key++;
return(hashvalue % tablesize);
}
Position find(Elementtype key, hashtable H)
{
Position
P;
List L;
L=H-->thelists(Hash(key,H-->tablesize));
P=L-->next;
While(P!=NULL && P-->element !
=key) P=P-->next;
Return P;
}
Void insert(elementtype key, hashtable H)
{
Position pos,newcell;
List L;
Pos=find(key,H);
If(pos==NULL)
{
Newcell=malloc(sizeof(struct listnode));
If(newcell==NULL)
Fatalerror(“Out of
Space”); else
{
L=H-->thelists(hash(key,H-->tablesize));
Newcell-->next=L-->next;
Newcell-->element=key;
L-->next=Newcell;
}
}
}
ADVANTAGES:
Separate chaining is used when memory space is a concern.
It can be very easily
implemented. DISADVANTAGES:
It requires pointers which causes the algorithm to slow down a bit.
Unevenly distributed keys-long lists-search time increases.
Open Addressing
In an open addressing hashing system, if a collision occurs, alternative cells are tried until an empty cell is
found.
A bigger table is needed for open addressing hashing, than for separate chaining.
Types of Open Addressing :
1. Linear Probing.
2. Quadratic Probing.
3. Double Hashing. www.Vidyarthiplus.com
16
UNIT V
www.Vidyarthiplus.com
17
UNIT V
Linear Probing
It is a kind of Open Addressing. In Linear probing, F is a linear function of i, typically F(i)=i. In linear probing,
the position in which a key can be stored is found by sequentially searching all positions starting from the
position calculated by the hash function until an empty cell is found.
If the end of the table is reached and no empty cell have been found, then the search is continued from the
beginning of the table. It has a tendency to create cluster in the table.
In linear probing we get primary clustering problem. Primary Clustering Problem
If the Hashtable becomes half full and if a collision occurs, it is difficult to find an empty location in the hash
table and hence an insertion or the deletion process takes a longer time.
Hash function
hi(key)=(Hash(key)+ F(i)) % Tablesize F(i)=i Hash(key)=key % tablesize
Ex: 89,18,49,58,69
-> Hashtable
0 49
1 58
2 69
3
4
5
6
7
8 18
9
1.Hash(89)=89 % 10=9
2.Hash(18)=18 % 10= 8
3. Hash(49)=49 % 10=9 -> collision occurs for first time
i=1 h1(49)= (9+1) % 10=10 % 10 =0
4. Hash(58)= 58 % 10 =8 -> collision occurs for first time
i=1 h1(58)= (8+1) % 10 =9 -> collision occurs for first time
i=2 h2(58)= (8+2) % 10 =0 -> collision occurs for first time
i=3 h3(58)= (8+3) % 10 =1
5. Hash(69)=69%10=9 -> collision occurs for first time i=1
h1(69)= (9+1) % 10 =9 -> collision occurs for first time
i=2 h2(69)= (9+2) % 10 =1 -> collision occurs for first
time i=3 h3(69)= (9+3) % 10 =2
Advantage:
It does not require pointers.
Disadvantage:
It forms clusters, which degrades the performance of the hash table for storing and retrieving data.
Quadratic Probing
It is a kind of open addressing technique.It is a collision resolution method that eliminates the primary
clustering problem of linear probing.
-> Hash function hi(key)=(Hash(key)
+ F(i)) % Tablesize F(i)=i2
Hash(key)=key % tablesize
-> Hashtable Ex: 89,18,49,58,69
0 49
1 58
www.Vidyarthiplus.com
18
UNIT V
2 www.Vid6y9arthiplus.com
3
4
5
6
7 18
8 89
9
1.Hash(89)=89 % 10=9
2.Hash(18)=18 % 10= 8
3. Hash(49)=49 % 10=9 -> collision occurs for first time
i=1 h1(49)= (9+12) % 10=10 % 10 =0
4. Hash(58)= 58 % 10 =8 -> collision occurs for first time
i=1 h1(58)= (8+12) % 10 =9 -> collision occurs for first time
i=2 h2(58)= (8+22) % 10 =2
5. Hash(69)=69%10=9 -> collision occurs for first time i=1
h1(69)= (9+12) % 10 =9 -> collision occurs for first time
i=2 h2(69)= (9+22) % 10 =3
Secondary Clustering:
Elements that Hash to the same position will probe the same alternative cells. This is known as secondary clustering.
Double Hashing
Double hashing is a technique which belongs to open addressing. Open addressing is a collision resolution
technique which uses the concept of linked lists. Open addressing handles collision by trying out all the
alternative cells until an empty cell is found. Collision is said to have occurred if there exists this
situation.i.e., If an element inserted hashes to the same value as that of an already inserted element, then
there is collision PROCEDURE:
Compute the positions where the data elements are to be inserted by applying the first
hash function to it.
Insert the elements if the positions are vacant.
If there is collision then apply the second hash function.
Add the two values and insert the element into the appropriate position.
Number of probes for the data element is 1 if it is inserted after calculating first hash function.
Number of probes is 2 if it is inserted after calculating second hash function.
DEFINITION:
It is a collision resolution technique which uses two hash functions to handle collision.
The interval (i.e., the distance it probes) is decided by the second hash function which is independent.
REQUIREMENTS:
The table size should be chosen in such a way that it is prime so that all the cells can be inserted. The second
hash function should be chosen in such a way that the function does not evaluate to zero.i.e., 1 can be
added to the hash function(non-zero). To overcome secondary clustering, double hashing is used. The
collision function is,
hi(key)=(Hash(key)+ F(i)) %
Tablesize F(i) = i * hash2 (X)
Where hash2(X) = R – (X % R) R is a prime number. It should be smaller than the tablesize
Example 1 :
19
UNIT V
89, 18, 49, 58, 69,60
0 69
1
2 60
3 58
4
5
6 49
7 18
8 89
9
49
h0(49)=9
h1(49) = (9+(1*7)) % 10 = (9+7) % 10 = 16 % 10 = 6
58
7 – (58 % 7) = 7 – 2 = 5
i=1
h1(58) = (8+(1*5)) % 10 = 13 % 10 = 3
69
7 – (69 % 7) = 7 – 6 = 1
h1(69) = (9+1) % 10 = 10 % 10 = 0
60
7 – (60 % 7) = 7 – 4 = 3
h1(60) = (0+1*3) % 10 =
3 h2(60) = (0+2*3) % 10
= 6 h3(60) = (0+9) % 10 =
9 h4(60)=(0+12)%10=2
APPLICATIONS:
It is used in caches.
It is used in finding duplicate records.
Used in finding similar records.
Finding similar substrings.
ADVANTAGES:
No index storage is required.
It provides rapid updates.
DISADVANTAGES:
Problem arises when the keys are too small.
There is no sequential retrieval of keys.
Insertion is more random.
Re-Hashing:
It is a technique in which the table is re-sized i.e., the size of the table is doubled by creating a new table.
Rehashing is a technique that is used to improve the efficiency of the closed hashing techniques. This can be
done by reducing the running time. If the tab le g e t s t o o f u ll , t h e r u n ning time for the
w w w . V i d y a r th i p l u s. c o m
operations will start
20
UNIT V
21
UNIT V
taking too long and inserts might fail for clowsewdwh.aVshidinygarwthiitphluqsu.acodmratic resolution. This
can happen if there are too many deletions intermixed with insertions. A solution, then, is to build another
table that is about twice as big (with associated new hash function) and scan down the entire original hash
table, computing the new hash value for each (non-deleted) element and inserting it in the new tableRe-
Hashing is required when, The table is completely filled in the case of double-Hashing
The table is half-filled in the case of quadratic and linear probing
The insertion fails due to overflow.
IMPLEMENTATION:
Rehashing can be implemented
in 1.Linear probing
2. Double hashing
3.Quadratic
probing
Rehashing can be implemented in several ways with quadratic probing.
One alternative is to rehash as soon as the table is half full.
The other extreme is to rehash only when an insertion fails.
A third, middle of the road, strategy is to rehash when the table reaches a certain load factor.Since
performance does degrade as the load factor increases, the third strategy, implemented with a
good cutoff, could be best.
Problems:
1. According to linear
0 6
1 15
2 23
3 24
4
5
6 13
Rehashing
Size=7 double size=14 next prime =17
1. 16 % 17 = 6
2. 15 % 17 = 15
3. 23 % 17 = 6
h1(X) = 6 + 1 % 17 = 7
4. 24 % 17 = 7
h1(24) = 7 + 1 % 17 = 8
5. 13 % 17 = 13
0
1
2
3
4 www.Vidyarthiplus.com
22
UNIT V
5 www.Vidyarthiplus.com
16
7 23
8 24
9
10
11
12
13 13
14
15 15
16
Advantage:
This technique provides the programmer the flexibility to enlarge the table size if required.
Disadvantages:
Transfer time is more.
Extensible Hashing
• insert(10010)
directory for k = 3
www.Vidyarthiplus.com
23
UNIT V
insert(11011)
1. Advantages:
o Extendable hashing provides performance that does not degrade as the file grows.
o Minimal space overhead - no buckets need be reserved for future use. Bucket address table
only contains one pointer for each hash value of current prefix length.
2. Disadvantages:
o Extra level of indirection in the bucket address table
o Added complexity
www.Vidyarthiplus.com
24