Documente Academic
Documente Profesional
Documente Cultură
Structures – Introduction, Features of Structures. Declaration and Initialization of Structures, Accessing structure
members, structure initialization. Nested Structures, Array of Structures, Arrays within structures and Pointers to
Structures, Structures and Functions, Bit Fields, Unions, Union of Structures. Example Programs on the topics
mentioned above.
Unit II- File Input/Output: Introduction, Types of Files, File I/O Operations- High level I/O functions- Open & Close a file,
Read and Write data into a file, Searching data in the file, Error handling during I/O operations on files. Command Line
Arguments, Applications of Command Line Arguments. Example Programs on the topics covered in this unit.
Unit III- Introduction to data structures: classification of data structures, dynamic memory allocation functions in C
language. Stacks: Definition, Various representation methods, operations on stacks and their implementation in C
language, applications of stacks.
Unit IV- Queues: Definition, Various representation methods, operations on queues and their implementation in C
language, applications of queues. Circular queues- operations on circular queues and their implementation in C
language.
Unit V- Linked lists: Definition, Various representation methods, operations on linked lists and their implementation in
C language.
Sorting techniques- Bubble Sort, Selection Sort, Quick Sort, Insertion Sort, and Merge Sort. Implementation of all the
above mentioned techniques in C language and trace them by giving different test data.
UNIT-I
STRUCTURES AND UNIONS
As we have seen earlier, Arrays can be used to represent a group of data items that belong to
the same data type, such as int (or) float. However we cannot use an array if we want to represent a
collection of data items of different types using a single name. Fortunately, c supports a constructed
data type known as structures which is a mechanism for packing of data belong to different data
types. A structure is a convenient tool for handling a group of logically related data items. For
example is an employee record that consists of the name, date of birth, address, salary, ID number
etc. of the person involved. A structure allows the programmer to group all these properties into one
unit. Structures help to organize complex data in a more meaningful way.
Examples:
time : seconds,minutes,hours
date : day,month,year
book : author,title,price,year
address: name,doornumber,street,city
customer : name,telephone,city,catagory
Features of Structures:
To copy elements of one array to another array of same data type elements are copied one by
one. It is not possible to copy elements at a time. Where as in structure it is possible to copy
the contents of all structure elements of different data types to another structure variable of its
type using assignment (=) operator. It is possible because structure elements are stored in
successive memory locations.
Nesting of structures is possible i.e. one can create structure within the structure. Using this
feature one can handle complex data types.
It is possible to pass structure elements to a function. This is similar to passing an ordinary
variable to a function. One can pass individual structure elements (or) entire structure by
value (or) address.
It is also possible to create structure pointers. We can also create a pointer pointing to
structure elements. For this we require “->‟ operator.
Define a structure:
Definition: A structure is a collection of one or more variables grouped together under a single name
for convenient handling. Here the variables that are grouped together can have different types.
(or)
A structure is a collection of heterogeneous data elements.
(or)
C Structure is a collection of different data types which are grouped together and each element in a C
structure is called member.
If you want to access structure members in C, structure variable should be declared.
Many structure variables can be declared for same structure and memory will be allocated for each
separately.
It is a best practice to initialize a structure to null while declaring, if we don’t assign any values to
structure members.
Defining a structure: structure must be defined first their format and that may be used later to
declare structure variables. Structure is defined using a keyword struct followed by the name of the
structure (optional) followed by the body of the structure. The members of the structure are declared
within the structure body. The general format of defining a structure is
Syntax: struct struct-name
{
data_type var-name1;
data_type var-name2;
.
.
data_type var-nameN;
};
Example: struct book_bank
{
char title[20];
char author[15];
int pages;
float price;
};
The keyword struct declares a structure to hold the details of structure members(or)structure
elements .Each member may belong to a different type .structure name is the identifier which
represents the name of the structure and is also called as structure tag. The tag name may be used
subsequently to declare variables that have the tags structure. The structure body contains structure
members(or)structure elements .For example
Example: struct book_bank
{
char title[20];
char author[15];
int pages;
float price;
};
Declaring structure variables: After defining a structure format we can declare variables of that
type. we can declare structure variables using the structure-tag anywhere in the program. A structure
variable declaration is similar to the declaration of variables of any other data types. It includes the
following elements.
definitions, such as #define. In such cases, the definition is global and can be used by other
functions as well.
Accessing the Members of a structure: we can access and assign values to the members of
structure in a number of ways. As we mentioned earlier, the members of the structure themselves are
not the variables. They should be linked to the structure variable in order to make them meaningful
members. The link between a member and a variable is established using the member operator '.'
which is also known as 'dot operator'(or) period operator.
For example, book1.price is the variable representing the price of book1.
Here we can see how we would assign values to the members of book1
strcpy(book1.title,”basic”);
strcpy(book1.author,”balagurusamy”);
book1.pages=240;
book1.price=120.36;
We can also use scanf to give the values through the keyboard
scanf(“%s”,book1.title);
scanf(“%d”,&book1.pages);
Example: Define a structure type, struct personal that would contain person name, date of joining
and salary, using this structure, write a c program to read this information for one person from the
keyboard and print the same on the screen.
#include<stdio.h>
struct personal
{
char name[20];
int day;
char month[10];
int year;
float salary;
};
main()
{
struct personal person;
printf(“input values”);
scanf(“%s%d%s%d%f”,person.name,&person.day, person.month,
&person.year,&person.salary);
printf(“%s%d%d%d%f”,person.name,person.day,person.month,person.year,
person.salary);
}
Example #include <stdio.h>
#include <string.h>
struct student
{
int id;
char name[20];
float percentage;
} record;
main()
{
record.id=1;
strcpy(record.name, "Raju");
record.percentage = 86.5;
printf(" Id is: %d \n", record.id);
printf(" Name is: %s \n", record.name);
printf(" Percentage is: %f \n", record.percentage);
}
Example: #include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
main( )
{
struct Books Book1; /* Declare Book1 of type Book */
struct Books Book2; /* Declare Book2 of type Book */
/* book 1 specification */
strcpy( Book1.title, "C Programming");
strcpy( Book1.author, "Nuha Ali");
strcpy( Book1.subject, "C Programming Tutorial");
Book1.book_id = 6495407;
/* book 2 specification */
strcpy( Book2.title, "Telecom Billing");
strcpy( Book2.author, "Zara Ali");
strcpy( Book2.subject, "Telecom Billing Tutorial");
Book2.book_id = 6495700;
/* print Book1 info */
printf( "Book 1 title : %s\n", Book1.title);
printf( "Book 1 author : %s\n", Book1.author);
printf( "Book 1 subject : %s\n", Book1.subject);
printf( "Book 1 book_id : %d\n", Book1.book_id);
/* print Book2 info */
printf( "Book 2 title : %s\n", Book2.title);
printf( "Book 2 author : %s\n", Book2.author);
printf( "Book 2 subject : %s\n", Book2.subject);
printf( "Book 2 book_id : %d\n", Book2.book_id);
}
Output: Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
in braces.
A terminating semicolon.
Rules for initializing structures:
We cannot initialize individual members inside the structure template.
The order of values enclosed in braces must match the order of members in the structure
definition.
It is permitted to have partial initialization. we can initialize only the first few members and
leave the remaining blank. The uninitialized members should be only at the end of the list.
The uninitialized members will be assigned default values as follows.
zero for integer and floating point numbers.
'\0' for character strings.
Example: write program for demonstrating structure member initialization
#include<stdio.h>
void main()
{
struct student /*Declaraing the student structure*/
{
int marks1,marks2,parks3;
};
struct student std1=(55,66,80):/*initializing ,marks for student 1*/
struct student std2=(60,85,78):/initializing marks for student 2*/
clrscr();
/*Displaying marks for student 1*/
print(“marks obtained by 1st student: %d and
%d”,std1.marks1,std1.marks2.std1.marks3);
/*Displaying marks for student 2*/
printf(*\nMarks obtained by 2nd student:
%d.%d”,std2.marks1.std2.marks2.std2.marks3);
getch();
}
Copying & Comparing Structure Variables: Two variables of the same structure type can be
copied the same way as ordinary variables. If person1 and person2 belongs to the same structure,
then the fallowing assignment operations are valid:
person1 = person2; ------ assigns person1 to person2
person2 = person1; ------ assigns person2 to person1
However, the statements such as,
person1 = = person2
person1! = person 2 are not permitted.
C does not permit any logical operations on structure variables. In such cases, we need to compare
them by comparing the members individually.
Example: program to illustrate the comparison & copying of structure variables
#include<stdio.h>
struct class
{
CSE DEPT. G RAJASEKHAR REDDY Page 8
C LANGUAGE
int no;
char name[20];
float per;
};
main()
{
int x;
struct class stu1={111,”Ramu”,72.50};
struct class stu2={222,”Reddy”,67.00};
struct class stu3;
stu3=stu2;
x=(stu2.no==stu3.no&&stu2.per==stu3.per)?1:0;
if(x==1)
printf(“\n student2 and student3 are same\n”);
else
printf(“\n student2 and student3 are different\n”);
}
Operations on Individual Members of the Structure: As pointed earlier, the individual members
are identified using the member operator (.). A member with the dot operator along with its structure
variable can be treated like any other variable name and therefore it can be manipulated using
expressions and operators. Consider the previous example program; we can perform the following
operations.
if( stu1.no = = 111)
stu1.per +=10.00;
float sum =stu1. per + stu2.per;
stu2.per *= 0.5;
We can also apply the increment and decrement operators to numeric type members. For example,
the following statements are valid:
stu1.no++;
++ stu2.no;
Example: C Program to Store Information (name, roll and marks) of a Student Using Structure
#include <stdio.h>
struct student
{
char name[50];
int roll;
float marks;
};
main()
{
struct student s;
printf("Enter information of students:\n\n");
printf("Enter name: ");
scanf("%s",s.name);
printf("Enter roll number: ");
scanf("%d",&s.roll);
CSE DEPT. G RAJASEKHAR REDDY Page 9
C LANGUAGE
An inner-most member in a nested-structure can be accessed by chaining all the concerned structure
variables (from outer-most to inner-most) with the member using the dot operator. The fallowing
statements are invalid:
employee.allowance ------------- actual member is missing
employee.house_rent ------------- inner structure variable is missing
We can also use tag names to define inner structures. For example,
struct pay
{
int da;
int hra;
};
struct salary
{
char name[10];
struct pay allowance;
struct pay arrears;
};
struct salary employee [100];
Here, pay template is defined outside the salary template and is used to define the structure of
allowance and arrears inside the salary structure. C permits nesting up to 15 levels
The pay structure members can be referred to as:
employee.allowance.da;
employee.allowance.hra;
employee.arrears.da;
employee.arrears.hra;
Example: #include <stdio.h>
struct Employee
{
char ename[20];
int ssn;
float salary;
struct date
{
int date;
int month;
int year;
}doj;
}emp = {"Pritesh",1000,1000.50,{22,6,1990}};
int main()
{
printf("\nEmployee Name : %s",emp.ename);
printf("\nEmployee SSN : %d",emp.ssn);
printf("\nEmployee Salary : %f",emp.salary);
printf("\nEmployee DOJ : %d/%d/%d",
emp.doj.date,emp.doj.month,emp.doj.year);
CSE DEPT. G RAJASEKHAR REDDY Page 11
C LANGUAGE
}
Output : Employee Name : Pritesh
Employee SSN : 1000
Employee Salary : 1000.500000
Employee DOJ : 22/6/1990
Example: implement following student information fields using nested structures
#include<stdio.h>
#include<conio.h>
void main()
{
struct student;
{
int roll_no;
struct name
{
char First[20];
char Middle[20];
char Last[20];
}st_name;
struct dob
{
int day ,month,year;
}std_dob;
struct course
{
char elective 1[20];
char elective2[20];
}st_course;
};
struct student std1;
clrscr();
std.roll_no=34;
strcpy(sdt1.st_name.First,”Krishna”);
strcpy(sdt1.st_name.Middle,”sai”);
strcpy(sdt1.st_name.Last,”reddy”);
std1.st_dob.day=21;
std1.st_dob.month=12;
std1.st_dob.year=1993;
strcpy(std1.st_course.elective1,”Mechanics”);
strcpy(std1.st_course.elective2,”Animation”);
Printf(“\nRoll No.:%d”,std1.Roll _No);
Printf(“\n Name: %s%s%s”,
std1.st_name.First,std1.st_name.Middle,std1.st_name.Last);
Printf(“\n Date of birth(DD MM YYYY):%d%d%d”,
std1.st_dob.day,std1.st_dob.Month,std1.st_dob.Year);
Printf(“\ncourse electives:%s&%s”,
std1.st_course.elective1,std1.st_course.elcetive2);
getch();
}
Example: Implement the following employee information fields using nested structures
#include<stdio.h>
#include<conio.h>
CSE DEPT. G RAJASEKHAR REDDY Page 12
C LANGUAGE
void main()
{
struct employee
{
int emp_id;
struct name
{
char First[20];
char Mibble[20];
char Last[20];
}emp_name;
char doj[20];
struct G_sal
{
float basic,HRA;
float spl_allow;
}emp_sal;
};
struct employee emp1l
clrscr();
emp1.emp_id=37;
strcpy(emp1.emp_name.first,”M”);
strcpy(emp1.emp_name.middle,”Mahesh”);
strcpy(emp1.emp_name.last,”reddy”);
strcpy(emp1.doj,”22/10/2004”);
emp1.emp_sal.basic=17432.00;
emp1.emp_sal.HRA=10032.00;
emp1.emp_sal.spl_allow=5000.00;
Printf(“\n emp id:%d”, emp1.emp_id);
Printf(“\n name:%s%s%s”,emp1.emp_name.First ,emp1.emp_name.Middle
,emp1.emp_name.Last);
Printf(“\n date of joining (DD MM YYYY): %s”,emp1.doj);
Printf(“\n Gross salary:%.2f”,
emp1.emp_sal.basic+emp1.emp_sal.HRA+emp1.emp_sal.spl_allow);
getch();
}
Arrays of Structures: As you know, C Structure is collection of different data types ( variables )
which are grouped together. Whereas, array of structures is nothing but collection of structures.
Arrays of structures represent each element of an array must be structure type. For example, in
analyzing the marks obtained by a class of students, we may use a template to describe student name
and marks obtained in various subjects and then declare all the students as structure variables. In
such cases, we may declare an array of structures, each element of the array representing a structure
variable.
Syntax: struct structurename
{
datatype var1;
datatype var2;
.
.
datatype varN;
}structurevariable[size];
(or)
struct structurename structurevariable[size];
Example: struct class student [100];
The above defines an array called „student‟ that consists of 100 elements. Each element is defined
to be of the type struct class.
Consider the following declaration:
struct marks
{
int eng;
int tel;
int sci;
};
main( )
{
struct marks student[3]={45,76,87},{78,68,79},{34,23,14};
................
................
}
This declares the student as an array of three elements student [0], student [1],student [2] and
initializes the members as follows:
student[0].eng=45;
student[0].tel=76;
.......................
.......................
student[2].sci=14;
Example: write a program to calculate the subject-wise and student-wise totals and store as a
part of the structure
#include<stdio.h>
struct marks
{
int eng;
int tel;
int sci;
int tot;
};
main( )
{
int i;
struct marks student[3]={{45,67,81,0},{75,53,69,0},{57,36,71,0}};
struct marks t={0,0,0,0};
clrscr();
for(i=0;i<3;i++)
{
student[i].tot=student[i].eng+student[i].tel+student[i].sci;
t.eng=t.eng+student[i].eng;
t.tel=t.tel+student[i].tel;
t.sci=t.sci+student[i].sci;
t.tot=t.tot+student[i].tot;
}
int total;
};
struct marks student[3]= {10,20,30,0,10,20,30,0,10,20,30,0};
struct marks t={0,0,0,0};
int i,j,k=0;
clrscr();
for(i=0;i<=2;i++,k++) /* „i? represent student*/
{
for(j=0;j<=2;j++) /* „j? represent subjects */
{
student[i].total+=student[i].sub[j];
t.sub[i]+=student[i].sub[i];
}
t. total+= student[i].total;
}
printf("\nSTUDENT TOTAL\n\n");
for(i=0;i<=2;i++)
printf("student[%d] %d\n", i+1,student[i].total);
printf("\nSUBJECT TOTAL\n\n");
for(k=0;k<=2;k++)
printf("subject-%d\t %d\n",k+1,t.sub[k]);
printf("\nGrand Total = %d\n", t.total);
getch();
}
Structures and Functions: C supports the passing of structure values as arguments to a function.
There are three methods by which the values of a structure can be transferred from one function to
another.
The first method is to pass each member of the structure as an actual argument of the function
call. The actual arguments are then read independently like ordinary variables. This is the
most elementary approach and becomes unmanageable and inefficient when the structure size
is large.
The second method involves passing of a copy of the entire structure to the called function
[Like, call by value]. Since the function is working on a copy of the structure, any changes to
the structure members within the function are not reflected in the original structure.
Therefore, it is necessary for the function to return the entire structure back to the calling
function.
Note: All the compilers may not support this method of passing the entire structure as a
parameter.
The third approach employs a concept called pointers to pass the structure as an argument. In
this case, the address location of the structure is passed to the called function. The function
can access indirectly the entire structure and work on it. This is similar to the way, arrays are
passed to functions. This method is more efficient as compared to the second one.
CSE DEPT. G RAJASEKHAR REDDY Page 16
C LANGUAGE
Passing individual structure member as an argument to a function: Here we can pass individual
structure members as an argument to a function.
Example: Write a c program to simulate the multiplication of two fractions by passing
individual structure members to a function
#include<stdio.h>
struct fraction
{
int num;
int denom;
};
struct fraction multiply(int,int,int,int);
main()
{
struct fraction f1,f2,result;
clrscr();
printf("\nEnter numerator and denominator of first fraction:");
scanf("%d%d",&f1.num,&f2.denom);
printf("\nEnter numerator and denominator of second fraction:");
scanf("%d%d",&f2.num,&f2.denom);
result=multiply(f1.num,f1.denom,f2.num,f2.denom);
printf("\nThe result after multiplication of two fractions is:");
printf("\n%d / %d",result.num,result.denom);
}
struct fraction multiply(int a,int b,int x,int y)
{
struct fraction r;
r.num=a*x;
r.denom=b*y;
return r;
}
Passing structure by value (call by value):A structure variable can be passed as an argument as
normal variable to the called function. If structure is passed by value, change made in structure
variable in the called function does not reflect in original structure variable in the calling function.
General format of sending a copy of a structure to the called function:
function name (structure_variable_name);
The called function takes the fallowing form:
data type function name (struct_type structvariablename)
{
-----------
-----------
return (expression);
}
Important points to remember:
The called function must be declared for its type, appropriate to the data type it is expected to
return. For example, if it is returning a copy of the entire structure, then it must be declared as
struct with an appropriate tag name.
The structure variable used as the actual argument and the corresponding formal argument in
the called function must be of the same struct type.
The return statement is necessary only when the function is returning some data. The
expression may be any simple variable or structure variable or an expression using simple
variables.
When a function returns a structure variable, it must be assigned to a structure variable of
identical type in the calling function.
The called function must be declared in the calling function, if it is placed after the calling
function.
Example: write a c program which illustrates sending a structure variable through call by
value.
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct sbook
{
int pages;
float price;
char title[20],author[30],publisher[30];
};
void dispalybook(struct sbook book1)
{
book1.price+=10.00;
book1.pages+=20;
}
main()
{
struct sbook sb={“c language”,”raja”,100.65,25,”technical”);
clrscr();
printf(“\n The book details before the functioncall is”);
printf(“Titles:%s”,book1.title);
printf(“Author:%s”,book1.author);
printf(“Price:%f”,book1.price);
printf(“pages:%d”,book1.pages);
printf(“Publisher:%s”,book1.publisher);
displaybook(sb);
printf(“\n The book details after the function call”);
printf(“Titles:%s”,book1.title);
printf(“Author:%s”,book1.author);
printf(“Price:%f”,book1.price);
printf(“pages:%d”,book1.pages);
printf(“Publisher:%s”,book1.publisher);
getch();
}
Example: Write a C program to create a structure student, containing name and roll. Ask user
the name and roll of a student in main function. Pass this structure to a function and display
the information in that function.
#include <stdio.h>
struct student
{
char name[50];
int roll;
};
void Display(struct student stu);
main()
{
struct student s1;
printf("Enter student's name: ");
scanf("%s",s1.name);
printf("Enter roll number:");
scanf("%d",&s1.roll);
Display(s1); // passing structure variable s1 as argument
}
void Display(struct student stu)
{
printf("Output\nName: %s",stu.name);
printf("\nRoll: %d",stu.roll);
}
Example: Write a simple program to illustrate the method of sending an entire structure as a
parameter to a function(Passing a copy of the entire structure as an argument to a function).
#include<stdio.h>
#include<conio.h>
struct stores
{
char name[20];
float price;
int qty;
};
main( )
{
struct stores update(struct stores,float,int);
float mul(struct stores);
float p_inc,val;
int q_inc;
struct stores item={"pen",5.50,10};
clrscr();
printf("\nInput increment values :");
printf("\nprice increment and quantity increment\n");
scanf("%f %d",&p_inc,&q_inc);
item=update(item,p_inc,q_inc); /*function call*/
printf("\nUpdate values of item:\n");
printf("Name :%s\n",item.name);
printf("Price:%f\n",item.price);
CSE DEPT. G RAJASEKHAR REDDY Page 19
C LANGUAGE
printf("Quantity :%d\n",item.qty);
val=mul(item); /*function call*/
printf("\nValue of the item=%f\n",val);
getch();
}
struct stores update(struct stores prod,float p,int q)
{
prod.price+=p;
prod.qty+=q;
return(prod);
}
float mul(struct stores stock)
{
return(stock.price * stock.qty);
}
Example: Write a c program to simulate the multiplication of two fractions by passing entire
structure as an argument to a function.
#include<stdio.h>
struct fraction
{
int num;
int denom;
};
struct fraction multiply(struct fraction,struct fraction);
main()
{
struct fraction f1,f2,result;
clrscr();
printf("\nEnter numerator and denominator of first fraction:");
scanf("%d%d",&f1.num,&f1.denom);
printf("\nEnter numerator and denominator of second fraction:");
scanf("%d%d",&f2.num,&f2.denom);
result=multiply(f1,f2);
printf("\nThe result after multiplication of two fractions is:");
printf("\n%d / %d",result.num, result.denom);
}
struct fraction multiply(struct fraction x struct fraction y)
{
struct fraction r;
r.num=x.num*y.num;
r.denom=x.denom*y.denom;
return r;
}
Passing structure by reference (call by reference): An address of structure variable can be passed
as an argument to the called function. If structure is passed by reference, any change made in
structure variable in the called function does reflect in original structure variable in the calling
function.
General format of sending address of a structure to the called function:
function name (&structure_variable_name);
main( )
{
struct book
{
char title[25];
char author[25];
int no;
};
struct book b={“ RGM „C‟ Notes”,”DCSE”,9};
struct book *ptr;
ptr=&b;
printf(“%s %s %d\n”,b.tittle,b.author,b.no);
printf(“%s %s %d\n”, ptr->tittle,ptr->author,ptr->no);
}
Output: RGM C Notes DCSE 9
RGM C Notes DCSE 9
Explanation: The first printf( ) is as usual way of accessing the members of the structure. The
second printf( ) however is peculiar. We cannot use ptr.tittle, ptr.author and ptr.no because ptr is not
a structure variable but it is a pointer to a structure, and the dot operator requires a structure variable
on its left. So, In such cases C provides an operator -> called as an arrow operator to refers the
structure elements.
Example: C Program to illustrate the use structure pointers.
struct invent
{
char name[20];
int number;
float price;
};
main( )
{
struct invent product[3], *p;
clrscr( );
printf(“\n INPUT \n\n”);
for( p = product; p<product+3; p++)
scanf(“%s %d %f”,p->name, &p->number, &p->price);
printf(“\nOUTPUT\n\n”);
p=product;
while(p < product +3)
{
printf(“%-20s %5d %11.5f\n”, p->name, p -> number, p ->price);
p++;
}
getch( );
}
Accessing Structure Members with Pointer:To access members of structure with
structure variable, we used the dot( .) Operator. But when we have a pointer of
structure type, we use arrow ->to access structure members.
#include<stdio.h>
CSE DEPT. G RAJASEKHAR REDDY Page 23
C LANGUAGE
struct Book
{
char name[10];
int price;
}
int main()
{
struct Book b;
struct Book* ptr = &b;
ptr->name = "Dan Brown"; //Accessing Structure Members
ptr->price = 500;
}
#include<stdio.h>
struct team
{
char *name;
int members;
char captain[20];
}t1 = {"India",11,"Dhoni"} , *sptr = &t1;
main()
{
printf("\nTeam : %s",(*sptr).name);
printf("\nMemebers : %d",sptr->members);
printf("\nCaptain : %s",(*sptr).captain);
}
Example: write a program to implement the problem in example one using pointer notation.
#include<stdio.h>
#include<conio.h>
void main( )
{
struct student
{
int marks1,marks2,marks3;
}s1,s2;
struct student *std1,*std2;
clrscr( );
std1=&s1;
std2=&s2;
std1->marks1=55;
std1->marks2=66;
std1->marks3=80;
std2->marks1=60;
std2->marks2=85;
std2->marks3=78;
Printf(“marks obtained by 1st student: %d , %d and %d”,
std1->marks1,std1->marks2,std1->marks3);
Printf(“\n marks obtained by second student: %d and %d”,
std2->marks1,std2->marks2,std2->marks3);
getch( );
CSE DEPT. G RAJASEKHAR REDDY Page 24
C LANGUAGE
}
Example: implement the problem in example using pointer notation.
#include<stdio.h>
#include<conio.h>
void main()
{
struct student;
{
int marks1,marks2,marks3,sum;
float avg;
}s1;
struct student *std1;
clrscr();
std1=&s1;
Printf(Enter the marks obtained by the student in three subjects : “);
scanf(“%d%d%d “,&s1.marks1 ,&s1.marks2,&s1.marks3);
std1 ->sum=std->marks1+std1->marks2+std1->marks3;
std1->avg=(std1->marks1+std1->marks2+std1->marks3)/3;
Printf(“sum=%d\navg=%.2f”,std1->sum,std1->avg);
getch();
}
Size of structures: We normally use structures and arrays to create variables if larger sizes. The
actual size of these variables in terms of bytes may change form machine to machine. We may use
the unary operator sizeof() to tell us the size of a structure.
The expression,
sizeof(struct x)
will evaluate the number of bytes required to hold all the members of the structure x.
If y is a simple structure variable of type struct x, then the expression,
sizeof (y)
would also give the same answer.However,if y is an array variable of type struct x.
Example: program to display the size of a structure variable.
#include<stdio.h>
#include<conio.h>
void main()
{
struct s
{
int a;
char b;
float c;
long d;
}s1;
Printf(“\n size of (s1)=%d”,sizeof(s1));
getch();
}
Example: program to display the size of a structure variable.
#include<stdio.h>
struct book
CSE DEPT. G RAJASEKHAR REDDY Page 25
C LANGUAGE
{
char bname[30];
int ssn;
int pages;
};
main()
{
struct book b1;
printf("\nSize of bname : %d",sizeof(b1.bname));
printf("\nSize of ssn : %d",sizeof(b1.ssn));
printf("\nSize of pages : %d",sizeof(b1.pages));
printf("\nSize of Structure : %d",sizeof(b1));
}
Bit fields: Bit fields are the special features provided in “C‟ to change the order of allocation of
memory from bytes to bits. Generally, when storing integer values for the member of a structure
variable,the memory allocated would be 2nytes(16 bits) for every integer to store data. There are
some occasions where data items require much less than 16 bits space. In such cases, we waste
memory space. That is ,if an integer value is 0(or)1 is stored in the integer member, it would use only
one bit of storage and remaining 15bits are unused. In such situations the programmer can use the
concept of bit fields and allocate only the required number of bits to the members of the structure
variables.
A bit field is a set of adjacent bits whose size can be from 1 to 16 bits in length. Therefore a word
can be divided into number of bitfields.The name and size of bit fields are defined using a structure.
General format of bit field definition:
struct tag_name
{
data type var_name1:bit_length;
data type var_name2:bit_length;
---------------------------------------
---------------------------------------
};
Where,
data type is either int or unsigned int or signed int.
bit length is the number of bits used for the specified variable name. Bit length is divided by
the range of value to be stored. The largest value that can be stored is 2n -1. Where, n is the
bit length.
The internal representation of bit fields is machine dependent. That is, it depends on the size of int
and the ordering of bits. Some machines store bits form left to right and others from right to left.
15 14 13 12 11 10 9 8 7 6 5 4 3 2
1 0
Bit fields cannot be the members of unions, but they can be members of the structures which
are themselves the members of unions.
It is possible to combine normal structure elements with bit-field elements.
Example: Using bit fields, Write a C program to store the information of vehicles.
#include<stdio.h>
main( )
{
struct vehicle
{
unsigned type: 3;
unsigned fuel: 2;
unsigned model: 3;
} V;
V.type=4;
V.fuel=2;
V.model=6;
printf(“Type of vehicle:%d\n”, V.type);
printf(“Fuel is %d\n”, V.fuel);
printf(“Model is %d\n);
getch( );
}
Example: write a c program which illustrates bit fields concept
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct test
{
int roll;
unsigned m1:7;
unsigned m2:7;
unsigned m3:7;
unsigned total:9;
unsigned result:1;
};
void main()
{
struct test s;
clrscr();
printf(“enter student roll number”);
scanf(“%d”,&s.roll);
s.m1=66;
s.m2=22;
s.m3=12;
if(s.m1<0||s.m1>100||s.m2<0||s.m2>100||s.m3<0||s.m3>100)
{
printf(“\n invalid marks”);
exit(0);
}
s.total=s.m1+s.m2+s.m3;
if(s.m1<35||s.m2<35||s.m3<35)
{
CSE DEPT. G RAJASEKHAR REDDY Page 28
C LANGUAGE
s.result=0;
}
else
{
result=1;
}
printf(“\n student results for the test”);
printf(“\n roll number %d”,s.roll);
printf(“\n marks in first subject %d”,s.m1);
printf(“\n marks in second subject %d”,s.m2);
printf(“\n marks in third subject %d”,s.m3);
printf(“\n total marks %d”,s.total);
(s.result)?printf((“\n result: pass”):printf(“\n result: fail);
getch();
}
Unions: Unions are a concept borrowed from structures and therefore it follows the same syntax as
structures. However there is major distinction between them is, in terms of storage. In structures,
each member has its own storage location, whereas all the members of a union use the same location.
This implies that, although a union may contain many members of different types, it can handle only
one member at a time. Like structures, a union can be declared using the keyword union as follows.
Definition: A union is a collection of heterogeneous data elements.
(or)
C Structure is a collection of different data types which are grouped together and each element in a C
structure is called member.
If you want to access union members in C, union variable should be declared.
Many union variables can be declared for same union and same memory will be allocated for all
members.
Defining a union: union must be defined first their format and that may be used later to declare
union variables. Union is defined using a keyword union followed by the name of the union-tag
followed by the body of the union. The members of the union are declared within the union body.
The general format of defining a union is
Syntax: union union-name
{
data_type var-name1;
data_type var-name2;
.
.
data_type var-nameN;
};
Example: union book_bank
{
char title[20];
char author[15];
int pages;
float price;
CSE DEPT. G RAJASEKHAR REDDY Page 29
C LANGUAGE
};
The keyword union declares a union to hold the details of union members (or) union elements .Each
member may belong to a different type .union-name is the identifier which represents the name of
the union and is also called as union tag. The tag name may be used subsequently to declare
variables that have the tags union. The union body contains union members (or)union elements .For
example
Example: union book_bank
{
char title[20];
char author[15];
int pages;
float price;
};
Declaring union variables: After defining a union format we can declare variables of that type.we
can declare union variables using the union_tag anywhere in the program. A union variable
declaration is similar to the declaration of variables of any other data types. It includes the following
elements.
The keyword union
The union tag name
List of variable names separated by commas
A terminating semicolon
Syntax: union union_tag union_var1,union _var2,........union _varN;
Example: union book_bank book1,book2,book3;
Example:
union class
{
int marks;
float average;
char grade;
} student;
The memory allocated to the union variables is not the sum of the memory sizes of all its members,
instead memory allocated for the union variable is equal to the largest member memory size. In the
above example memory is allocated for union variable student is 4 bytes only.and any member of
student can take value. But the value is stored in the allotted 4 bytes only. If another member takes
value, then the value previously taken by the other member is erased and new member value is stored
in the same 4 bytes.
Accessing Union elements: To access a union member we can use the same syntax that we use for
structure members.
Syntax: union_variablename.union_member_name;
Example: union class
{
CSE DEPT. G RAJASEKHAR REDDY Page 30
C LANGUAGE
int marks;
float average;
char grade;
} student;
Now we will see how to access union members
student.marks;
student.average; ....and so on.
During accessing, we should make sure that we are accessing the member whose value is currently
stored. For example, the statements such as,
student.marks=65;
student.average=65.0;
printf(“%d”, student.marks);
would produce erroneous output (which is machine independent).
A union creates a storage location that can be used by any one of it's members at a time. When a
different member is assigned a new value, this new value supersedes the previous member's value.
Unions may be used in all places where a structure is allowed. The notation for accessing a union
member, which is nested inside a structure, remains the same as for the nested structures.
Example: Write a C Program to use structure within union. Display the contents of structure
elements.
main( )
{
struct x
{
float f;
char p[2];
};
union z
{
struct x set;
}
union z st;
st.set.f = 5.5;
st.set.p[0]= 65;
st.set.p[1]=66;
clrscr();
printf(“\n%f\t%c\t%c”, st.set.f,st.set.p[0],st.set.p[1]);
getch( );
}
Difference between union and structure: Though unions are similar to structure in so many ways, the
difference between them is crucial to understand. This can be demonstrated by this example:
#include <stdio.h>
union job
{
char name[32];
CSE DEPT. G RAJASEKHAR REDDY Page 31
C LANGUAGE
float salary;
int worker_no;
}u;
struct job1
{
char name[32];
float salary;
int worker_no;
}s;
main()
{
printf("size of union = %d",sizeof(u));
printf("\nsize of structure = %d", sizeof(s));
}
Output: size of union = 32
size of structure = 40
There is difference in memory allocation between union and structure as suggested in above example. The
amount of memory required to store a structure variables is the sum of memory size of all members.
But, the memory required to store a union variable is the memory required for largest element of an union.
1 The keyword struct is used to define a The keyword union is used to define a union.
structure
4 The address of each member will be in The address is same for all the members of a
ascending order This indicates that memory union. This indicates that every member begins
for each member will start at different offset at the same offset value.
values.
5 Altering the value of a member will not Altering the value of any of the member will
affect other members of the structure. alter other member values.
6 Individual member can be accessed at a Only one member can be accessed at a time.
time
7 Several members of a structure can initialize Only the first member of a union can be
at once. initialized.
Example: C Program to Store Information of Students Using Structure
struct student
{
char name[50];
int roll;
float marks;
};
main()
{
struct student s[10];
int i;
printf("Enter information of students:\n");
for(i=0;i<10;++i)
{
s[i].roll=i+1;
printf("\nFor roll number %d\n",s[i].roll);
printf("Enter name: ");
scanf("%s",s[i].name);
printf("Enter marks: ");
scanf("%f",&s[i].marks);
printf("\n");
}
printf("Displaying information of students:\n\n");
for(i=0;i<10;++i)
{
printf("\nInformation for roll number %d:\n",i+1);
printf("Name: ");
puts(s[i].name);
printf("Marks: %.1f",s[i].marks);
}
}
Output: Enter information of students:
For roll number 1
Enter name: Tom
Enter marks: 98
For roll number 2
Enter name: Jerry
Enter marks: 89
Displaying information of students:
Information for roll number 1:
Name: Tom
Marks: 98
.
.
Program: C Program Write a Program to add, subtract, multiply and divide two complex
number
#include <stdio.h>
#include <conio.h>
struct complex
{
float real, imag;
}a, b, c;
struct complex read1(void);
void write1(struct complex);
struct complex add(struct complex, struct complex);
struct complex sub(struct complex, struct complex);
struct complex mul(struct complex, struct complex);
struct complex div(struct complex, struct complex);
void main ()
{
printf("Enter the 1st complex number\n ");
a = read1();
write1(a);
printf("Enter the 2nd complex number\n");
b = read1();
write1(b);
printf("Addition\n ");
c = add(a, b);
write1(c);
printf("Substraction\n ");
c = sub(a, b);
write1(c);
printf("Multiplication\n");
c = mul(a, b);
write1(c);
printf("Division\n");
c = div(a, b);
write1(c);
getch();
}
struct complex read1(void)
{
struct complex t;
printf("Enter the real part\n");
scanf("%f", &t.real);
printf("Enter the imaginary part\n");
scanf("%f", &t.imag);
return t;
}
void write1(struct complex a)
{
printf("Complex number is\n");
printf(" %.1f + i %.1f", a.real, a.imag);
printf("\n");
}
struct complex add(struct complex p, struct complex q)
{
struct complex t;
t.real = (p.real + q.real);
t.imag = (p.imag + q.imag);
return t;
}
struct complex sub(struct complex p, struct complex q)
{
struct complex t;
t.real = (p.real - q.real);
t.imag = (p.imag - q.imag);
return t;
}
struct complex mul(struct complex p, struct complex q)
{
struct complex t;
t.real=(p.real * q.real) - (p.imag * q.imag);
t.imag=(p.real * q.imag) + (p.imag * q.real);
return t;
}
struct complex div(struct complex p, struct complex q)
{
struct complex t;
t.real = ((p.imag * q.real) - (p.real * q.imag)) / ((q.real * q.real) + (q.imag * q.imag));
t.imag = ((p.real * q.real) + (p.imag * q.imag)) / ((q.real * q.real) + (q.imag *
q.imag));
return(t);
}
Input & Output: Enter the real part 2
Enter the imaginary part 4
Complex number is 2.0 + i4.0
Enter the real part 4
Enter the imaginary part 2
Complex number is 4.0 + i2.0
Addition
Complex number is 6.0 + i6.0
Subtraction
Complex number is -2.0 + i2.0
Multiplication
Complex number is 0.0 + i20.0
Division
Complex number is 0.6 + i0.8
Example: C Program Write a Program to add, subtract and multiply two complex number
#include<stdio.h>
#include<conio.h>
struct complex
{
int r,i;
};
void read1(struct complex *);
struct complex add(struct complex *,struct complex *);
struct complex sub(struct complex *,struct complex *);
CSE DEPT. G RAJASEKHAR REDDY Page 36
C LANGUAGE
}
}
}
COMP read1()
{
COMP c;
scanf("%d%d",&c.real,&c.img);
return c;
}
void write1(COMP c)
{
if(c.img < 0)
printf("\n %d -i %d",c.real,c.img);
else
printf("\n %d +i %d",c.real,c.img);
}
COMP add(COMP c1,COMP c2)
{
COMP r;
r.real= c1.real+c2.real;
r.img=c1.img+c2.img;
return r;
}
COMP multiply(COMP c1,COMP c2)
{
COMP r;
r.real=c1.real*c2.real-c1.img*c2.img;
r.img=c1.img*c2.real + c1.real*c2.img;
return r;
}
Example: Write a C program that uses functions to perform the following operations using Structure:
1.Reading a complex number
2.Writing a complex number
3.Addition of two complex numbers
4.Multiplication of two complex numbers
#include <stdio.h>
#include <stdlib.h>
struct complex
{
int real, img;
};
struct complex a, b, c;
main()
{
int choice, temp1, temp2, temp3;
while(1)
{
printf("Press 1 to add two complex numbers.\n");
printf("Press 2 to multiply two complex numbers.\n");
printf("Press 3 to exit.\n");
printf("Enter your choice\n");
scanf("%d",&choice);
switch(choice)
{
case 1: read1();
add();
break;
case 2:read1();
CSE DEPT. G RAJASEKHAR REDDY Page 39
C LANGUAGE
mul();
break;
case 3: exit(0);
default: exit(0);
}
}
}
read1()
{
printf("Enter a and b where a + ib is the first complex number.");
printf("\na = ");
scanf("%d", &a.real);
printf("b = ");
scanf("%d", &a.img);
printf("Enter c and d where c + id is the second complex number.");
printf("\nc = ");
scanf("%d", &b.real);
printf("d = ");
scanf("%d", &b.img);
}
add()
{
c.real = a.real + b.real;
c.img = a.img + b.img;
if ( c.img >= 0 )
printf("Sum of two complex numbers = %d + %di",c.real,c.img);
else
printf("Sum of two complex numbers = %d %di",c.real,c.img);
}
mul()
{
c.real = a.real*b.real - a.img*b.img;
c.img = a.img*b.real + a.real*b.img;
if ( c.img >= 0 )
printf("Multiplication of two complex numbers = %d + %di",c.real,c.img);
else
printf("Multiplication of two complex numbers = %d %di",c.real,c.img);
}
Example: program that uses a simple structure for storing different student details
#include<stdio.h>
#include<conio.h>
void main()
{
int num,i=0;
struct student
{
char name[30];
int rollno;
int marks;
};
struct student std[10];
clrscr();
printf(“enter the number of students”);
scanf(“%d”,&num);
for(i=0;i<num;i++)
{
CSE DEPT. G RAJASEKHAR REDDY Page 40
C LANGUAGE
person.name,&person.day,person.month,&person.year,&person.salary);
/*displaying the values*/
Printf(“%s %d %s %d,%.2f\n”,
person.name,person.day,person.month,person.year,person.salary);
getch( );
}
Example: write a program for realizing complex numbers using structures.
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main( )
{
stuct complex
{
double real;
double img;
};
struct complex c1,c2, c3;
clrscr( );
Printf(“\n enter two complex numbers(x+iy):\n\n real part of 1 number:”);
scanf(“%lf”,&c1.real);
Printf(“\n imaginary part of first number:”);
scanf(“&lf”,c1.img);
Printf(“\n real part of second number”);
scanf(“%lf”,&c2.real);
Printf(“\n imaginary part of second number:”);
scanf(“%lf”,&c2.img);
c3.real=c1.real+c2.real;
c3.img=c1.img+c2.img;
Printf(“\n\n%.2lf+(%.2lf)i+ %.2lf+(%.2lf)i= %.2lf+
(%.2lf)I”.c1.real,c1.img,c2.real,c2.img,c3.real,c3.img);
getch( );
}
Example: write a program to read marks obtained by student in three sub and compute its
sum and average .
#include<stdio.h>
#include<conio.h>
void main( )
{
struct student
{
int marks1,marks2,marks3,sum;
float avg;
};
struct student std1;
clrscr( );
Printf(“enter the marks obtained by student in three subjects”);
scanf(“%d %d %d”,&std1.marks1,&std1.marks2,&std1.marks3);
std.sum=std1.marks1+std1.marks2+std1.marks3;
Std1.avg=(std1.marks1+std1.marks2+std1.marks3)/3;
Printf(“sum=%d\n avg=%.2f”,std1.sum,std1.avg);
getch( );
}
Example: write a program that uses the sizeof operator to differentiate between structures and
unions.
#include<stdio.h>
#include<conio.h>
void main()
{
struct s
{
int a;
char b;
float c;
long d;
}s1;
union u
{
int a;
char b;
float c;
long d;
}ul;
clrscr();
Printf(“\n size of (s1) = %d”,sizeof(s1));
Printf(“\n size of (u1) = %d”,sizeof(ul));
getch();
}
UNIT-II
FILES
Until now we are using the functions such as scanf() is used to read the data from the
keyboard and printf() is used to display the result on the video display unit. These are console
oriented input output functions, which always use the terminal (keyboard and monitor) as the target
place. These functions will work well when input data is very small. But many real life problems
have large volumes of input data, In such situations the console oriented input output operations has
two major problems.
It is very difficult to input large volume of data through terminals.
It is time consuming to enter large volume of data using keyboard.
When we are entering the data through the keyboard, if the program is terminated for any of the
reason (or) computer is turned off, the entire input data is lost.
To overcome all these problems, we introduced a concept called files. Here, the data can be stored
on the discs, and we can access data whenever required (any number of times) without destroying the
data. These method employees a concept of files to store data.
Definition: A file represents a sequence of bytes on the disk where a group of related data is
stored.
(or)
A file is defined as a collection of related data stored in auxiliary devices such as hard disks,
CD’s etc.,
(or)
File is a set of records that can be accessed through the set of library functions.
Generally, File is created for permanent storage of data. While entering the data into a file,
data is recorded on the auxiliary devices in the form of 0’s & 1’s (called bits). The auxiliary devices
will not assign any relationship between the various bits. C supports a number of functions that have
the ability perform the basic file operations .They are
naming a file
opening a file
reading data from a file
writing data to a file
closing a file
We have two different ways to perform file operations in c language. The first one is known as low-
level I/O, which uses UNIX system calls. The second method is known as high-level I/O operations,
which uses function in c's standard I/O library.
File types: C programming can handle files in two ways
CSE DEPT. G RAJASEKHAR REDDY Page 44
C LANGUAGE
Stream oriented data file:Stream means reading and writing of data. In this form of files, reading
and writing is easier and are mostly used. Stream oriented data files are again divided into two types
base on the format in which the data is stored.
Text files.
Binary files.
System Oriented data files: These are also called as low-level files, are closely associated with the
os and are difficult to work with them. These type files require a separate set of functions to work
with.
Text file: As the name suggests, text file stores textual information like alphabets, numbers, special
symbols.etc. In actually, the ASCII code of textual characters is stored in the text files. But, since
data stored in a stored in a storage device in the binary format, The text file contents are first
converted in the binary form before actually being stored in the storage device. In other words, we
can say that the text file store the ASCII encrypted information. A text file can store different
character sets such as
Uppercase English alphabets(A to Z)
Lowercase English alphabets(a to z)
Numeric characters (like 1,2,3...)
Punctuation characters (like :,:,?..etc)
Special symbols ($,%..etc)
The text files are stored with .txt (or) .doc extension. C language supports various operations for
manipulating data stored in a text file (write, append..etc).A text file can be a stream of characters
that a computer can process sequentially. It is not only processed sequentially but only in forward
direction. For this reason a text file is usually opened for only one kind of operation (reading,
writing, or appending) at any given time.
Binary file:As the name suggests, a binary file stores the information in the form of binary form,
that is, in the same format as it is stored in the memory. Thus, the use of binary file eliminates the
need of data conversion from text to binary format for storage purpose. However, one of the main
drawback of binary file is that the data stored in a binary file is not in human understandable form.
Any file which stores the data in the form of bytes that is 8-bit representation is known as binary file.
Every executable file is generated by the c compiler is a binary file. Examples are .exe, video stream
files, image files etc. C language supports binary file operation such as read, write and append with
the help of various built in functions.
Accessing files: We can access files in two ways
1) Sequential access
2) Random access
Sequential access: In sequential access reading of data starts from the beginning of the file and continuous
sequentially until the required is found. If we want to read the last record of the file we need to read all the
records before that. It takes more time. If we desire to access the 10th record, then the first 9 records should
be read sequentially for reaching to the 10th record.
Random access: In random access data can be read & modified randomly. In this file we want to read the
last record of the file, we can read it directly from the position where it is stored in the file, and It takes less
time as compared to sequential file.
File I/O functions (or) operations: we have two different ways to perform file operations in c
language. The first one is known as low-level I/O, which uses UNIX system calls. The second
method is known as high-level I/O operations, which uses function in c's standard I/O library. Here
we will discuss high-level I/O operations only.
High-Level I/O functions (or) operations: A File I/o operation uses functions in c's standard
library. The c library provides many file operation functions. They are
ftell() It returns the current position of the pointer in the file(in terms of bytes
from starting)
ferror() This function will report error occurred during read/write operations.
Defining a file: If we want to store data in a file in the secondary memory, we must specify certain
things about the file, to the operating system. They include:
file name
data structure
purpose
Filename: It is a string of characters that make up a valid file name for the operating system. It
contains two parts, a primary name and an optional period with the extension.
Example: input.data
store.txt
prog.c
Data structure: data structure of a file is defined as FILE in the library of standard I/O function
definitions. Therefore, all file should be declared as type FILE before they are used. FILE is a
defined data type.
Purpose: when we open a file, we must specify what we want to do with the file. For example, we
may write data to a file (or) read already existed data.
Declare a file pointer variable: A file pointer variable should be declared as a pointer to a structure
of type FILE as shown below:
Syntax: FILE * file_pointer_name;
FILE: FILE is the derived data type which is defined already in header file stdio.h as a structure.
The structure details are hidden from the programmer and this structure is used to store information
about a file.
*file_pointer_name: It is the name of the file pointer of type FILE. Here the file pointer can be used
as either a global (or) a local variable. The file pointer fp can be used to open a file, update file and to
close a file in sequence.
Opening a file:The file should be opened before reading a file (or) before writing into file. fopen()
function is used to open a file. The syntax to open a file for either read / write operation is
Syntax: FILE *fp;
fp= fopen (char * filename, char * mode)
The first statement declares the variable fp as a pointer to the data type FILE.
The second statement opens the file and assigns an identifier to the file type pointer fp, and this
statement has two parameters.
File name holds the name of the file to be opened. The filename should be a valid identifier. The file
in a c program can also contain path information.
Mode informs to the library function about the purpose of opening a file. Mode can be any one of
the following.
Mode Purpose
This mode is used for opening as existing file to perform read operation.
The various features of this mode are:
1. It is used only for the text file.
r(read mode)
2. If the file does not exist, an error is returned.
3. The contents of the file are not lost.
4. The file pointer points to the beginning
This mode is used to create a file. The various features of this mode are:
1. It is used only for the text file.
w (write mode) 2. If the file does not exist, a file is created.
3. If the file already exists, the original contents of the file are lost.
4. The file pointer points to the beginning
This mode is used to insert data at the end of existing file. The various
a (append features of this mode are:
1. Used only for the text file.
mode) 2. If the file does not exist, a file is created.
3. If the file already exists, a file pointer points to the end.
r+ This mode is used for open a file to perform read and write, if the file
already exists. Otherwise, will return NULL.
It deletes all the contents of an existing file and both writing and reading
w+ can be done a fresh. If the file does not exist, then it creates a new file for
writing and reading.
a+ Opens the file to read and write and write at the end of the file.
This mode is used to create a file. The various features of this mode are:
1. Used only for binary file.
wb(write
2. If the file does not exist, a file is created.
mode) 3. If the file already exists, the original contents of the file are lost.
4. The file pointer points to the beginning.
This mode is used to insert the data at the end of the existing file.The
various features of this mode are:
1. Used only for binary file.
ab(append 2. If the file does not exist, a file is created
mode) 3. If the file already exists, the file pointer points to the end
4. The new data is inserted at the end
5. Existing data cannot be modified.
rb+ This mode is used for open a file to perform read and write, if the file
already exists. Otherwise, will return NULL.
It deletes all the contents of an existing file and both writing and reading
wb+ can be done a fresh. If the file does not exist, then it creates a new file for
writing and reading.
ab+ Opens the file to read and write and write at the end of the file.
Note: both filename and modes are specified as strings. They should be enclosed in double quotation
marks.
Example: FILE *p1;
FILE *p2;
p1=fopen(“data.dat”,”r”);
p2=fopen(“result.dat”,”w”);
The function fopen() may return the following value:
if(fp = = NULL)
{
printf(“error in opening file \n”);
exit (0);
}
(or)
FILE *fp;
if(fp=fopen(“data.txt”,”r”)==NULL)
{
printf(“cannot open data.txt file”);
exit(0);
}
closing a file:A file must be closed as soon as all the operations on it have been completed. The
close of a file is the last operation to be performed on a file. A file can be closed using fclose()
function. This ensures that all buffers are flushed & all the links to the file are broken. This function
also prevents any accidental misuse of the file. Once the file is closed, to access the file, it has to be
reopened.
The fclose() function returns
zero(0)if a file is closed successfully.
EOF if a file not closed successfully.
Syntax: fclose(file_pointer);
Example: FILE * p1,*p2;;
p1 = fopen(“data.dat”, “w”);
p2=fopen(“data.dat”,”r”);
----------------
----------------
fclose(p1);
fclose(p2);
----------------
----------------
The above program opens two files and closes then after all operations on them are completed. Once
a file is closed, its file pointer can be used for another file.
Writing/Reading data to/from a file: Once the file opened, we must perform reading data from a
file (or) writing data to a file can be done using the standard I/O functions.
Character oriented I/O functions: we have two character oriented I/O functions, they are putc()
and getc().These are very much similar to putchar() and getchar() functions and handle one character
at a time.
putc():This function is used to write a single character to a file. The syntax of putc() function is
Syntax: putc( character, file_pointer);
Assume a file is opened with mode “w” and file pointer fp1, then
putc(c,fp1);
The above statement writes the character contained in character variable 'c' to the file associated with
file pointer fp1.
getc(): This function is used to read a single character from a file. The syntax of getc() function is
syntax: c=getc (file_pointer);
Example: c=getc(fp2);
The above statement would read a character from a file whose file_pointer is fp2.
The file pointer moves by one character position for every operation of getc() and
putc().The getc() will returns the character pointer to by file pointer fp, On success. Otherwise it
returns end-of-file marker EOF, when end of the file has been reached. Therefore, the reading should
be terminated when EOF is encountered.
Example: write a c program to read data from the keyboard. write it a file called input. data,
again read same data from the input.dat file, and display it on the screen.
#include<stdio.h>
main()
{
FILE *f1;
char c;
printf(“\n\n data input”);
f1=fopen(“input.dat”,”w”);
while((c=getchar())!=EOF)
{
putc(c,f1);
}
fclose(f1);
printf(“\n\n data outptut”);
f1=fopen(“input.dat”,”r”);
while((c=getc(f1))!=EOF)
{
printf(“%c”,c);
}
fclose(f1);
}
Example: #include<stdio.h>
#include<process.h>
void main( )
{
CSE DEPT. G RAJASEKHAR REDDY Page 51
C LANGUAGE
FILE * fp1;
FILE * fp2;
char file1[10];
char file2[10];
int ch;
printf(“enter input file \n”);
scanf( “%s”, file);
if ((fp1 = fopen(file1, “r”)) = = NULL)
{
printf(“Opening input file failed \n”);
exit (0);
}
printf(“ enter output file \n”);
scanf (“%s”, file2);
fp2 = fopen (file2, “w”);
if (fp2 = = NULL)
{
printf(“opening output file failed \n”);
exit(0);
}
while ((ch = getc(fp)) != EOF)
{
putc (ch, fp);
}
fclose (fp1);
fclose (fp2);
}
Integer oriented I/O functions: The getw() and putw() are integer oriented I/O functions. They are
very much similar to getc() and putc() functions and are used to read and write integer values. These
functions would be useful when we deal with only integer data. These functions can handle one
integer value at a time.
putw(): This function is used to write a single integer value to a file. The syntax for putw() is
syntax: putw(integer,filepointer);
getw(): This function is used to read a single integer value from a file. The syntax for getw() is
syntax: getw(filepointer);
Example: A file named data contains a series of integer numbers. code a program to read these
numbers and then write all odd numbers to a file to be called odd and all even numbers to a
file to be called even.
#include<stdio.h>
main()
{
FILE *f1,*f2,*f3;
int number,i;
printf(“contents of data file\n\n”);
f1=fopen(“data”,”w”);
for(i=1;i<=30;i++)
{
CSE DEPT. G RAJASEKHAR REDDY Page 52
C LANGUAGE
scanf(“%d”,&number);
if(number==-1)
break;
putw(number,f1);
}
fclose(f1);
f1=fopen(“data”,”r”);
f2=fopen(“odd”,”w”);
f3=fopen(“even”,”w”);
while((number=getw(f1))!=EOF)
{
if(number%2==0)
putw(number,f3);
else
putw(number,f2);
}
fclose(f1);
fclose(f2);
fclose(f3);
f2=fopen(“odd”,”r”);
f3=fopen(“even”,”r”);
printf(“\n\n contents of odd file”);
while((number=getw(f2))!=EOF)
{
printf(%4d”,number”);
}
printf(“\n\n contents of even file”);
while((number=getw(f3))!=EOF)
{
printf(“%4d”,number);
}
fclose(f2);
fclose(f3);
}
The fscanf() and fprintf() I/O functions: so far, we have seen functions ,that can handle only one
character (or) integer at a time. Most compilers support two other functions, namely fprintf() and
fscanf(),that can handle a group of mixed data simultaneously.
The functions fprintf() and fscanf() perform I/O operations that are identical to printf() and
scanf() functions, but they will work with files.
fprintf(): This function is used to write a group of mixed data to a file. The syntax is
syntax: fprintf(fp,”control_string”,list);
fp: fp is a filepointer associated with a file that has been opened for writing.
Control_string: It contains output specifications for the items in list.
List: It may include variables, constants and strings.
Example: fprintf(f1,”%s%d%f”,name,age,7.5);
The above statement represents name is the array variable of type char and age is int variable
fscanf():This function is used to read a group of mixed data from a file.The syntax is
syntax: fscanf(fp,”controlstring”,list);
fp: fp is a filepointer associated with a file that has been opened for reading.
Controlstring: It contains output specifications for the items in list.
List: It may include variables, constants and strings.
Example: fscanf(fp,”%s%d”,item,&quantity);
Example: write a c program which illustrate fprintf() and fscanf() functions.
#include<stdio.h>
main()
{
FILE *fp;
int I,roll,m1,m2,m3,total;
float percent;
char sname[20];
clrscr();
fp=fopen(“student.txt”,”w”);
if(fp==NULL)
{
printf(\n error in file creation”);
exit(0);
}
printf(“enter student details”);
for(i=0;i<2;i++)
{
printf(“\n enter roll number”);
scanf(“%d”,&roll);
printf(“\n enter name”);
scanf(“%s”,sname);
printf(“\n enter marks in three subjects”);
scanf(“%d%d%d”,&m1,&m2,&m3);
fprintf(fp,”%d%s%d%d%d”,roll,sname,m1,m2,m3);
}
fclose(fp);
fp=fopen(“student.txt”,”r”);
printf(“\n\n student results”);
printf(\n roll number \t name \t total \t percentage”);
for(i=0;i<2;i++)
{
fscanf(fp,”%d%s%d%d%d”,&roll,sname,&m1,&m2,&m3);
total=m1+m2+m3;
percent=total/3;
printf(“\n%d \t\t %s\t\t%d\t\t %f”,roll,sname,total,percent);
}
fclose(fp);
}
Note: The statement printf(“\n enter roll number”);
Which is equal to fprintf(stdout,”\nenter roll number”);
The statement scanf(%d”,&roll);
Which is equal to fscanf(stdin,”%d”,&roll);
CSE DEPT. G RAJASEKHAR REDDY Page 54
C LANGUAGE
Example: write a program to open a file named inventory and store in it the following data:
itemname number price quantity
aaa-1 111 17.50 115
bbb-2 125 36.50 75
ccc-3 247 31.25 104
Extend the program to read this data from the file inventory and display the inventory table
with the value of each item.
#include<stdio.h>
main()
{
FILE *fp;
int number,quantity,i;
float price,value;
char item]10],filename[20];
printf(“input file name\n”);
scanf(“%s”,filename);
fp=fopen(filename,”w”);
printf(“input inventory data\n”);
printf(“itemname number price quantity\n”);
for(i=1;i<=3;i++)
{
fscanf(stdin,”%s%d%f%d”,item,&number,&price,&quantity);
fprintf(fp,”%s%d%f%d”,item,number,price,quantity);
}
fclose(fp);
fprintf(stdout,”\n\n”);
fp=fopen(filename,”r”);
printf(“itemname number price quantity value\n”);
for(i=1;i<=3;i++)
{
fscanf(fp,”%s%d%f%d”,item,&number,&price,&quantity);
value=price*quantity;
fprintf(stdout,”%-8s %7d %8.2f %8d %11.2f”,
item,number,price,quantity,value);
}
fclose(fp);
}
String related I/O functions: These are useful for reading and writing entire lines of data to/from a
file. We have two functions.
fputs():The fputs() function writes the string (or) line of characters to a file. The null terminator is
not written. This function is similar to puts() function. The only difference is that with fputs()
function work with file. Also fputs() does not add new line to the end of the string; to include '\n' it
must explicitly specified. The fputs() function returns non negative on success and EOF on failure.
Syntax: fputs(char *str,FILE *fp);
(or)
fputs(stringvariable(or)stringconstant,fp);
*str: which is a pointer to the null terminated string to be written.
*fp: It is a file_pointer, which is associated with a file which has been opened for writing.
Example: #include<stdio.h>
main()
{
FILE *fp;
char c;
fp = fopen("op.txt","w");
fputs("Hello worldn",fp);
fclose(fp);
fp = fopen("op.txt","r");
while((c = fgetc(fp))!=EOF)
{
printf("%c", c);
}
fclose(fp);
}
Example: The following example shows the usage of fputs() function.
#include <stdio.h>
main ()
{
FILE *fp;
char c;
fp = fopen("file.txt", "w+");
fputs("This is c programming.", fp);
fputs("This is a system programming language.", fp);
fclose(fp);
fp = fopen("file.txt","r");
while((c = fgetc(fp))!==EOF)
{
printf("%c", c);
}
fclose(fp);
}
fgets():This function is used to read line of characters from a file.
Syntax: fgets(char *str, int n,FILE *fp)
(or)
fgets(stringvariable,size,fp);
The fgets() function reads n-1 characters from a file pointed to by fp and places the output into a
character array pointed to by str, and it will stop reading when any of the following conditions are
true.
It has read n-1 bytes (one character is reserved for null-terminator).
It encounters a newline characters.
It reaches the end of file.
A read error occurs.
This function automatically appends a null terminator to the data read.
This function returns
str ,If successful.
Block read and write I/O functions: The data are stored in the memory in the form of 0’s & 1’s
when read and write the binary files, the data transferred just as they found in memory & hence there
are no format conversions.
To read and write entire structure block, The functions fwrite() and fread() are used .Also
when we store large amount of data, it would be better to read and write in binary mode, as it
consumes less memory for data stored in the files. When we work on files in binary mode, we use
fread() and fwrite() functions.
fwrite():This function is used to write a structured block of data into a given file. The prototype of
fwrite() which is defined in header file “stdio.h” .
syntax: fwrite (void *ptr, int size, int n, FILE *fp);
ptr: The data to be written into the file should be stored in the memory. The address of the
first byte is stored in ptr.
size is the length of each item in bytes.
’n ‘ is the number of items to be written into the file.
fp is a file pointer of an opened file into which the data has to be written.
Example: write a c program to write a block of structure into a file using fwrite() function.
#include<stdio.h>
main()
{
FILE *fp;
char choice='y';
struct student
{
int age;
char gender;
char name[20];
};
struct student s;
clrscr();
fp=fopen(“student.txt”,”wb”);
if(fp==NULL)
{
printf(“\n error in file opening”);
exit(0);
}
do
{
printf(“\n enter student name”);
scanf(“%s”,s.name);
printf(“\n enter student age”);
scanf(“%d”,&s.age);
void main( )
{
FILE *fp;
int a[6] = {10,20,30,40,50,60};
int n , i;
char file_name [20];
printf( “enter the file name:\n”);
scanf(“%s”, file_name);
printf(“enter number of integers:\n”);
scanf(“%d”, &n);
if ((fp = fopen(file_name,”wb”))==NULL)
{
printf(“error in creating the file\n”);
exit(0);
}
fwrite(a, sizeof(int), n, fp);
}
fread():The fread() function is used to read a structured block of data from a given file. The
prototype of fread() which is defined in header file “stdio.h” is shown below.
Syntax: fread(void *ptr,int Size,int n,FILE *fp);
*ptr: The data read from the file should be stored in memory.It is required to allocate sufficient
memory and address of the first byte is stored in ptr.
Size: specifies the length of each item in Bytes.
n: Specifies “Number of Items to Be Read“.
*fp is a file pointer of an opened file from where the data has to be read.
The function fread() returns
Number of items, if successfully read.
return zero ,If no items have been read (or) when error has been occurred (or) end-of–file is
encountered.
{
int age;
char gender;
char name[20];
};
struct student s;
clrscr();
fp=fopen(“student.txt”,”rb”);
if(fp==NULL)
{
printf(“\n error in opening a file”);
exit(0);
}
printf(“\n student details read from a file”);
while(fread(&s,sizeof(s),1,fp)==1)
{
printf(“\n student name:%s”,s.name);
printf(“\n student age: %d”,s.age);
printf(\n student gender: %c”, s.gender);
}
getch();
fclose(fp);
}
Example: Write a C program to write all the members of an array of structures to a file using
fwrite(). Read the array from the file using fread() and display on the screen.
#include <stdio.h>
struct s
{
char name[50];
int height;
};
main()
{
struct s a[5],b[5];
FILE *fptr;
int i;
fptr=fopen("file.txt","wb");
for(i=0;i<5;++i)
{
printf("Enter name: ");
gets(a[i].name);
printf("Enter height: ");
scanf("%d",&a[i].height);
}
fwrite(a,sizeof(a),1,fptr);
fclose(fptr);
fptr=fopen("file.txt","rb");
fread(b,sizeof(b),1,fptr);
for(i=0;i<5;++i)
{
printf("Name: %s\nHeight: %d",b[i].name,b[i].height);
}
fclose(fptr);
}
Searching data in the file (or) random accessing file: In addition to accessing files sequentially,
random accessing is also possible. In certain occasions we are interested in accessing only a
particular part of file and not in reading the other parts. This can be achieved by changing the
file_pointer position. The functions ftell(), fseek() and rewind() are useful in random access to the
file.(These function are also called as file positioning functions)
ftell():The function ftell() gives the current position of the file pointer(in terms of bytes) from the
beginning of the file. This function returns a number of type long.
Syntax: long_variable=ftell(fp);
where fp is file pointer.
rewind():The function rewind ( ) is used to set the file pointer to the beginning of the file.
Syntax: rewind(fp);
When the data is written into the file, the file pointer points to the end of file. So, we can use the
function rewind() which will move the file pointer to the beginning of the file without closing &
reopening the file. After executing the function rewind(), the file pointer points to the beginning of
the file.
fseek():The function fseek() is used to set the file pointer at the specified position. This is used to
move the file pointer to the desired position within the file.
Syntax : fseek (fp, offset, position);
fp is a file pointer.
Offset can take +ve, -ve (or) zero and specifies the number of bytes to be moved from the
location specified by position.
position– position is an integer number and it can take one of the values as shown below:
Constant Value Position of file
SEEK-SET 0 Beginning of file
SEEK-CUR 1 Current position
SEEK-END 2 End of file
The function returns
Zero on success
Non zero value on failure.
else
{
printf(“\n position entered is invalid”);
}
fclose (fp);
}
Note: The difference between rewind (fp) and fseek (fp,0L,0) is, both the functions moves the
file pointer to the beginning of the file. So, functionality is same, but syntax & number of
parameters are different.
Error Handling During I/O operations (File status functions): There are several kinds of errors
occur, while we are performing various I/O operations on files in c language. If we are unable to
handle these errors, it may result in abnormal termination of the program (or) will give incorrect
output. Some of the most frequently error occurred situations during file I/O operations are.
Trying to read the data beyond the EOF
device overflow
Trying to use a file that has not been opened
Trying to perform an operation on a file, when the file is opened for another type of
operation.
Opening a file with invalid file name
Attempting to write protected file etc
To handle these types of error situations, c library supports two functions, namely, feof() and
ferror().
feof(): The feof() function is used to check whether the file_pointer associated with the file has
reached end of file (or) not.
Syntax: int feof(fp);
This function returns,
true (or) non zero value,if ths file pointer reaches EOF.
false (or) Zero,if not.
Example: #include <Stdio.h>
void main( )
{
FILE *fp;
-----------
fp= fopen (char *file name, char *mode)
------------
if (feof(fp))
{
printf(“end of file is reached \n”);
exit(0);
}
}
Where
ferror():This function is used to detects the error that occurred during read (or) write operation on a
file. A file can be opened in read (or) write mode. During reading data from a file or writing data into
a file following errors may occur:
Modifying read only file.
Trying to read a file which is opened in write mode.
Command line arguments: The interface which allows the user to interact with the computer by
providing instructions in the form of typed commands is called command line interface.
In the command prompt, the user types the commands. These commands are made up of equal sized
alpha numeric & other symbols.
Example: If user wants to execute a program to copy the contents of a file named x_FLE to another
one named Y_FILE, then we may use a command line like.
C:\> program X_FILE Y_FILE
In the above line, where program is the filename where the executable code of the program is stored.
This eliminates the need for the program to request the user to enter the filenames during execution.
Here “program X_FILE Y_FILE” means, the main function of program accepts the three arguments
namely program X_FILE and Y_FILE these parameters are called command line arguments.
Definition for command line arguments: As parameters are passed to the functions, similarly we
can also pass parameters to the function main() whenever the program is executed from the
command prompt. The words that are typed at the command prompt are passed to the function
main() of the program which is being-invoked at the command prompt. These arguments that are
passed by the operating system to the function main() when the program is invoked are called
command line arguments. To access the command line parameters the function main() should have
the following format:
syntax: void main(int argc, char *argv[] )
{
----------------------
----------------------
}
Where
argc is an argument counter that counts the number arguments on the command line.
argv is an argument vector and represents an array of character pointers that points to
command line arguments. The size of this array will be equal to the value of argc.strings that are part
of the command prompt are copied into argv[0], argv [1] and soon.
Argument vector and argument count with respect to command:
Example: c:\>copy T1.c T2.c
argv[0] copy
argv[1] T1.C
argv[2] T2.C
Since, there are three strings at the command line prompt; integer variable argc has the value3. The
value for the variable argc is not explicitly passed as the parameter and argv[0] will always have the
first parameter i.e., program name.
Example: Program to accept a file either through command line (or) as specified by user
during run-time and display the contents.
#include<stdio.h>
# include <process.h>
#include <string.h>
void main (int argc, char *argv[])
{
FILE *fp;
char fname [20];
char ch;
if (argc== 1)
{
printf (“enter file name:”);
scanf (“%s, f.name);
}
else
strcpy (fname, argv[1]);
fp = fopen (fname, “r”);
if(fp = = NULL)
{
printf (“file opening error \n”);
exit (0);
}
printf (“ the contents of file are: \n”);
printf (“-------\n”);
while ((ch = getc (fp)) != EOF)
printf (“%c”, ch);
}
Applications of command line arguments: The key application of command line argument is
runtime specification of data. That means the programmer must not statically include all the required
data with in the program but the same can be specified during runtime as well.
Example: write a c program to copy the contents of one file into another using the command
line arguments.
#include<stdio.h>
#include<conio.h>
main(int argc,char *argv[])
{
FILE *fs,*ft;
char ch;
clrscr();
if(argc!=3)
{
puts(“improper number of arguments”);
exit(0);
}
fs=fopen(argv[i],”r”);
if(fs==NULL)
{
printf(“source file cannot be opened”);
exit(0);
}
ft=fopen(argv[2],”w”);
if(ft==NULL)
{
printf(“target file cannot be opened”);
fclose(fs);
exit(0);
}
while(1)
{
ch=getc(fs);
if(ch==EOF)
break;
else
fputc(ch,ft);
CSE DEPT. G RAJASEKHAR REDDY Page 67
C LANGUAGE
}
fclose(fs);
fclose(ft);
printf(“\n file copy operation performed successfully”);
printf(“\n you can confirm the same by checking the destination file”);
getch();
}
Example: Write a ‘C’ program to copy content of one file into another file
#include<stdio.h>
void main()
{
FILE *fp1,*fp2;
char ch,fname1[20],fname2[20];
printf("\n enter sourse file name");
gets(fname1);
printf("\n enter sourse file name");
gets(fname2);
fp1=fopen(fname1,"r");
fp2=fopen(fname2,"w");
if(fp1==NULL||fp2==NULL)
{
printf("unable to open");
exit(0);
}
do
{
ch=fgetc(fp1);
fputc(ch,fp2);
}while(ch!=EOF);
fcloseall();
getch();
}
Example: C Program to merge contents of two files into a third file
#include <stdio.h>
main()
{
FILE *fp1 = fopen("file1.txt", "r");
FILE *fp2 = fopen("file2.txt", "r");
FILE *fp3 = fopen("file3.txt", "w");
char c;
if (fp1==NULL|| fp2==NULL||fp3==NULL)
{
puts("Could not open files");
exit(0);
}
while ((c = fgetc(fp1)) != EOF)
fputc(c, fp3);
while ((c = fgetc(fp2)) != EOF)
fputc(c, fp3);
printf("Merged file1.txt and file2.txt into file3.txt");
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
CSE DEPT. G RAJASEKHAR REDDY Page 68
C LANGUAGE
char c1;
clrscr();
fp=fopen("test.dat","r+");
printf("\n enter nuber of characters you want to reverse:");
scanf("%d",&n);
while(i<n)
{
c[i]=fgetc(fp)
i=i+1;
}
c[i]="\0";
rewind(fp);
strrev(c);
fputs(c,fp);
fclose(fp);
printf(“after reversing the data in file is\n”);
fp=fopen(“test.dat”,”r”);
while((c1=fgetc(fp))!=EOF)
{
printf(“%c”,c1);
}
fclose(fp);
}
Example: write a c program to copy last n characters from one file to another file.
#include<stdio.h>
main()
{
FILE *fp,*fp1;
char ch;
int num;
long length;
clrscr();
fp=fopen("source.dat","w");
printf("enter data in test.dat until you press’*’\n");
while((ch=getchar())!='*')
fputc(ch,fp);
fclose(fp);
printf("Enter the number of characters you want to copy : ");
scanf("%d", &num);
fp=fopen("source.dat","r");
if (fp==NULL)
{
puts("cannot open this file");
exit(1);
}
fseek(fp,0l,2);
length = ftell(fp);
fseek(fp,(length-num),0);
fp1=fopen("target.dat","w");
do
CSE DEPT. G RAJASEKHAR REDDY Page 70
C LANGUAGE
{
ch = fgetc(fp);
putc(ch,fp1);
}while (ch != EOF);
fcloseall();
fp1=fopen("target.dat","r");
while((ch=getc(fp1))!=EOF)
{
printf("%c",ch);
}
fclose(fp1);
getch();
}
UNIT-III
STACKS
Memory allocation: The C language supports two kinds of memory allocation through the variables
in C programs. Memory can be reserved for the variables either during compilation time or during
run time (Execution).
Static Allocation (compile time)
Dynamic Allocation (runtime)
Static Allocation: The method of allocating memory during compilation time is called “Static
Memory Allocation”. If the memory space is allocated (reserved) for various variables during
compilation time itself, the allocated memory space cannot be expanded to accommodate more data
or cannot be reduced to accommodate less data. In this technique, once the size of the memory
allocated is fixed, it cannot be altered even during execution time.
Example: int a[10];
During compilation, the compiler will allocate 10 memory locations for the variable “a”. In the worst
case, 10 elements can be inserted less than 10 elements lead to underutilization of allocated space
and more than 10 elements cannot be inserted.
Disadvantages:
The memory is allocated during compilation time. Hence, the memory allocated is fixed
and cannot be alerted during execution time.
Leads to underutilization if more memory is allocated.
Leads to overflow if less memory is allocated.
The static nature imposes certain limitations and can find their applications only when the data is
fixed and known before processing.
Dynamic Memory Allocation: The method of allocating memory during execution time is called
“dynamic memory allocation”. This allocation technique uses predefined functions to allocate and
release memory for data during execution time. So, if there is an unpredictable storage requirement,
then the dynamic allocation technique is used. Dynamic memory allocation functions are
malloc()
calloc()
free()
realloc()
Dynamic memory allocation functions: The exact size of array is unknown until the compile time, i.e.,
time when a compiler compiles code written in a programming language into a executable form. The
size of array you have declared initially can be sometimes insufficient and sometimes more than
required. But Dynamic memory allocation allows a program to obtain more memory space, while
running or to release space when no space is required. Although, C language inherently does not has
any technique to allocated memory dynamically, there are 4 library functions under "stdlib.h" for
dynamic memory allocation.
Function Use of Function
malloc() Allocates requested size of bytes and returns a pointer to the first byte
of the allocated space
calloc() Allocates space for an array elements, initializes them to zero and
then returns a pointer to memory
free() De-allocate the previously allocated space
realloc() Change the size of previously allocated space
malloc(): The name malloc stands for "memory allocation". The function malloc() reserves a block
of memory of specified size and return a pointer of type void which can be casted into pointer of any
type.Syntax of malloc() is
syntax: ptr=(cast-type*)malloc(byte-size)
ptr:It is pointer of cast-type.
Cast-type*:It is used to typecast the returned void pointer to any type.
Byte-size: which specifies block of memory to be allocated.
The malloc() function returns a pointer(of cast-type) to an area of memory with size of byte size. If
the space is insufficient, allocation fails and returns NULL pointer.
Examle: ptr=(int*)malloc(100*sizeof(int));
The above statement will allocate either 200 or 400 according to size of int 2 or 4 bytes respectively
for the pointer ptr and the pointer ptr points to the address of first byte of memory.
Example: cptr=(char *)malloc(10);
The above statement allocates 10 bytes of space for the pointer cptr of type char.
Note: the storage space allocated dynamically has no name and therefore its contents can be
accessed only through pointer.
We may also use malloc to allocate space for complex data types such as structures.
st_var=(struct store *)malloc(sizeof(struct store));
Here st_var is a pointer of type struct store.
Example: Write a C program to find sum of n elements entered by user. To perform this
Program, allocate memory dynamically using malloc() function.
#include <stdio.h>
#include <stdlib.h>
main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int));
if(ptr==NULL)
{
Example: Write a C program to find sum of n elements entered by user. To perform this
Program, allocate memory dynamically using calloc() function.
#include <stdio.h>
#include <stdlib.h>
main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int));
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
}
realloc():realloc() function is used to change the size of the previously allocated memory blocks. If
the previously allocated memory is not sufficient or much larger and we need more space for more
elements or we need reduced space for less elements then by the using the realloc function block size
can be maximize or minimize. Syntax of realloc() is
Syntax: ptr=realloc(ptr,new-size);
This function allocates a new memory space of size new-size to the pointer variable ptr and returns a
pointer to the first byte of new memory block.
This function returns, returns a NULL pointer when these function unsuccessful in locating
additional space.
Example: #include <stdio.h>
#include <stdlib.h>
main()
{
int *ptr,i,n1,n2;
printf("Enter size of array: ");
scanf("%d",&n1);
ptr=(int*)malloc(n1*sizeof(int));
printf("Address of previously allocated memory: ");
for(i=0;i<n1;++i)
printf("%u\t",ptr+i);
printf("\nEnter new size of array: ");
scanf("%d",&n2);
ptr=realloc(ptr,n2);
for(i=0;i<n2;++i)
printf("%u\t",ptr+i);
}
Differences between static memory allocation and dynamic memory allocation:
S.No Static Allocation Dynamic Allocation
1 Memory is allocated during compilation Memory is allocated during execution time.
time.
2 Used only when the data size is fixed and Used only for unpredictable memory
known in advanced before processing
requirement.
3 The size of the memory to be allocatedAsis and when memory is required, memory can be
fixed during compilation time and cannot be allocated. If not required, memory can be de-
altered during execution time. allocated. The size of the memory required may
vary during execution time
4 Execution is faster, since memory is already Execution is slower since memory has to
allocated and data manipulation is done on be
these allocated memory locations allocated during runtime. Data manipulation
is done only after allocating the
memory.
5 Memory is allocated either in stack area or Memory is allocated only in heap area.
data area. Example: array Example: Dynamic Arrays, Linked Lists
Difference between malloc() and calloc() functions in C
S.no malloc() calloc()
It allocates only single block of
1 It allocates multiple blocks of requested memory
requested memory
int *ptr;ptr=malloc( 20 * sizeof(int) ); int *ptr;Ptr=calloc( 20, 20 * sizeof(int));
2
For the above, 20*4 bytes of memory For the above, 20 blocks of memory will be created
only allocated in one block. and each contains 20*4 bytes of memory.
Total = 80 bytes Total = 1600 bytes
malloc () doesn’t initializes the allocated
3 calloc () initializes the allocated memory to zero
memory. It contains garbage values
type cast must be done since this
Same as malloc () function int *ptr;ptr = (int*)calloc(
4 function returns void pointer int *ptr;ptr
20, 20 * sizeof(int) );
= (int*)malloc(sizeof(int)*20 );
Stack Operations: The two basic operations associated with stacks are Push and Pop. Two
important per-conditions associated with push and pop operations are Overflow and Underflow,
respectively.
Push operation: The procedure of inserting a new element to the top of the stack is known as push
operation. The new element is added at the top most position of the stack. After every push
operation, the value of “top” is incremented by one. However before inserting the value we have to
check whether there is some space in the stack or not. If an attempt is made to insert a value in a
stack that is already full an error occurs. Therefore before inserting an element into the stack we have
to check the overflow condition.(Stack overflow: Attempt to insert an element when the stack is
full i.e top= STACK_SIZE-1).
Algorithm for push operation:
Step 1: if top== STACK_SIZE-1 then print “Stack is full”
Step 2: top=top+1
Step 3: stack[top]=element
Code for push operation (using global variables):
void push ()
{
int element;
printf(“enter the element to be pushed\n”);
scanf(“%d”,&element);
if (top==(STACK_SIZE-1))
printf("Stack is full");
else
{
top=top+1;
stack[top]=element;
}
}
In the above code array 'stack' and variable top are global variables. STACK_SIZE should be
#defined directive is called symbolic constant.
Pop operation: The procedure of removing element from the top of the stack is called pop
operation. In pop operation the topmost element from the stack will be deleted. After every pop
operation, the value of “top” is decremented by one. However before deleting an element from the
stack we have to see whether some element exists in the stack or not i.e if the stack is empty we
cannot do so. Therefore before deleting an element from the stack we have to check the underflow
condition.(Stack underflow : Attempt to delete an element when the stack is empty).
Algorithm for pop operation:
Step 1 : if top==-1 then print “stack is empty”
Step 2: print stack[top]
Code for push operation(using global variables):
void pop()
{
if(top==-1)
printf("stack is empty\n");
else
{
printf("%d is popped from stack\n",stack[top]);
top--;
}
}
CSE DEPT. G RAJASEKHAR REDDY Page 78
C LANGUAGE
In the above code array 'stack' and variable top are global variables.
Table for stack operations
Operation Definition
push The procedure of inserting a new element to the top of the stack is known
as Push Operation
pop The procedure of removing element from the top of the stack is called Pop
Operation.
display It displays all the elements of a stack
stack overflow Attempt to insert an element when the stack is full ie top= STACK_SIZE-1
stack underflow Attempt to delete an element when the stack is empty ie top=-1
Table for Values of Stack and Top
Operation Explanation
When an element is taken off from the stack, the operation is performed by pop(). Figure shows a stack
initially with three elements and shows the deletion of elements using pop()
Representation of stack using arrays: Let us consider a stack with 6 elements capacity. This is
called as the size of the stack. The number of elements to be added should not exceed the
maximum size of the stack. If we attempt to add new element beyond the maximum size, we
will encounter a stack overflow condition. Similarly, you cannot remove elements beyond the
base of the stack. If such is the case, we will reach a stack underflow condition. When an
element is added to a stack, the operation is performed by push().Figure 4.1 shows the creation
of a stack and addition of elements using push().(Note: Here initially top=0).
When an element is taken off from the stack, the operation is performed by pop(). Figure 4.2 shows a
stack initially with three elements and shows the deletion of elements using pop().
Implementation of Stack using Arrays: One of the two ways to implement a stack is by using a
one dimensional array. When implemented this way, the data is simply stored in the array. A variable
named “Top” is used to point to the top element of the stack. Each time data is added or removed,
Top is incremented or decremented accordingly, to keep track of the current Top of the stack.
Initially, the value of Top is set to -1 to indicate an empty stack. To push (insert ) an element onto
the stack, Top is incremented by one, and the element is pushed at that position. When Top reaches
SIZE-1 and an attempt is made to push a new element, then the stack overflows. Here, SIZE is the
maximum size of the stack. Similarly, to pop (remove) an element from the stack, the element on the
Top of the stack is displayed, and then Top is decremented by one. When the value of Top is equal to
-1 and an attempt is made to pop an element, the stack underflows.
Example: Write a C program to implement stack using arrays.
#include<stdio.h>
#define STACK_SIZE 4
int stack[STACK_SIZE];
int top=-1;
void push(int);
void pop();
void display();
void main()
{
int item, ch;
while(1)
{
printf("\n MAIN MENU");
printf("\n1.PUSH (Insert) in the Stack");
printf("\n2.POP (Delete) from the Stack");
printf("\n3.Display");
printf("\n4.Exit (End the Execution)");
printf("\nEnter Your Choice: ");
scanf("%d", &ch);
switch(ch)
{
case 1: printf("\nEnter the Element to be pushed");
scanf("%d", &item);
push(item);
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
}
}
}
void push (int element)
{
if (top==(STACK_SIZE-1))
printf("Stack overflow");
else
{
top=top+1;
stack[top]=element;
}
}
void pop()
{
if(top==-1)
printf("stack underflow\n");
else
{
printf("%d is popped from stack\n",stack[top]);
top--;
}
}
void display()
{
int i;
if (top==-1)
printf("stack is empty");
else
{
printf("the elements in the stack are");
for (i=top;i>=0;i--)
printf ("\n--------\n|%3d |\n--------",stack[i]);
}
}
Stacks implemented as arrays are useful if a fixed amount of data is to be used. However, if the
amount of data is not a fixed size or the amount of the data fluctuates widely during the stack’s life
time, then an array is a poor choice for implementing a stack.
Example: Source code for stack operations, using array (when top=0)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 6
int stack[MAX];
int top = 0;
int menu()
{
int ch;
clrscr();
printf("\n ... Stack operations using ARRAY... ");
printf("\n -----------**********-------------\n");
printf("\n 1. Push ");
printf("\n 2. Pop ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
CSE DEPT. G RAJASEKHAR REDDY Page 82
C LANGUAGE
scanf("%d", &ch);
return ch;
}
void display()
{
int i;
if(top==0)
{
printf("\n\nStack empty..");
}
else
{
printf("\n\nElements in stack:");
for(i = 0; i < top; i++)
printf("\t%d", stack[i]);
}
}
void pop()
{
if(top==0)
{
printf("\n\nStack Underflow..");
}
else
printf("\n\npopped element is: %d ", stack[--top]);
}
void push()
{
int data;
if(top==MAX)
{
printf("\n\nStack Overflow..");
}
else
{
printf("\n\nEnter data: ");
scanf("%d", &data);
stack[top] = data;
top = top + 1;
printf("\n\nData Pushed into the stack");
}
}
void main()
{
int ch;
do
{
ch=menu();
switch(ch)
{
case 1: push();
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
}
getch();
} while(1);
}
Dynamic implementation: A stack can be implemented using pointers, as a form of a linked list.
Dynamic implementation can be achieved using linked list as it is a dynamic data structure. The
limitations of static implementation can be removed using dynamic implementation. The memory is
efficiently utilized with pointers. Memory is allocated only after element is inserted to the stack. The
stack can grow or shrink as the program demands it to. However, if a small and/or fixed amount of
data is being dealt with, it is often simpler to implement the stack as an array.
Stack implementation using structures: A stack is implemented using an array, whenever a
function push() is called, we have to pass three parameters namely item, top and stack, where the
item is the element to be pushed, top is an integer value which is the index of the top most element in
the array stack. But the number of parameters increases, the overhead of passing parameters in
programming also increases and efficiency decrees. In such cases, we group all related items under a
common name using a structure and pass structures as parameters, which eventually reduces the
burden and increases the efficiency.
In our stack implementation, instead of passing two parameters top and stack, we can pass
only one parameter if we use structure. So a stack can be declared as a structure containing two
objects ie, an array to store the elements of the stack and an integer indicating the position of the top
most element in the array. The declaration is
#define MAXSIZE 5
struct stack
{
int stk[MAXSIZE];
int top;
};
struct stack s;
Here the elements can be accessed s.top and s.stk[top]
If the declaration is of the form
#define MAXSIZE 5
struct stack
{
int stk[MAXSIZE];
int top;
};
struct stack *s;
Here the elements can be accessed s->top and s->stk[top]
Source code for stack operations, using structures
#include <stdio.h>
#include <conio.h>
#define MAXSIZE 5
struct stack
{
int stk[MAXSIZE];
int top;
};
struct stack s;
void push ();
void pop();
void display ();
void main ()
{
int choice;
clrscr ();
s.top = -1;
printf ("STACK OPERATION\n");
while (1)
{
printf ("------------------------------------------\n");
printf (" 1 --> PUSH \n");
printf (" 2 --> POP \n");
printf (" 3 --> DISPLAY \n");
printf (" 4 --> EXIT \n");
printf ("------------------------------------------\n");
printf ("Enter your choice\n");
scanf ("%d", &choice);
switch (choice)
{
case 1: push();
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
}
}
}
void push ()
{
int num;
if (s.top==(MAXSIZE-1))
printf ("Stack is Full\n");
else
{
printf ("Enter the element to be pushed\n");
scanf ("%d", &num);
s.top=s.top+1;
s.stk[s.top]=num;
}
}
void pop ()
{
if (s.top==-1)
printf ("Stack is Empty\n");
else
{
printf ("poped element is = %d\n", s.stk[s.top]);
s.top = s.top - 1;
}
}
void display ()
{
int i;
if (s.top==-1)
printf ("Stack is empty\n");
else
{
printf ("\nThe status of the stack is\n");
for (i=s.top;i>=0;i--)
printf ("%d\n", s.stk[i]);
}
}
Applications of Stack:
Stack is used by compilers to check for balancing of parenthesis, brackets and braces.
Stack is used to evaluate prefix, postfix expressions.
Stack is used to convert an expression from one form to another form ie
Infix to postfix
Infix to prefix
Postfix to infix
Postfix to prefix
Prefix to infix
Prefix to postfix
In recursion, all intermediate arguments and return values are stored on the processors stack.
During a function call the return address and arguments are pushed onto a stack and on return
they are popped off.
Algebraic Expressions: An algebraic expression is a legal combination of operators and operands.
Operand is the quantity on which a mathematical operation is performed. Operand may be a variable
like x,y,z or a constant like 5,6,7,etc. operator is a symbol which signifies a mathematical or logical
operation between the operands. Consider an arithmetic expression, a+b*c. In this expression, the
addition operation is not evaluated first. This is because, operators are evaluated in the order their
precedence in the expression. So the entire equation is examined to determine whether there is any
operator with higher precedence. Examples of familiar operators include +,-,*,/,^ etc.
we consider five binary operations:+,-,*,/ $ or |and ^.for those binary operations, the following in the
order of precedence (highest to lowest):
operator precedence value
$ or ^ or | highest(3)
*,/,% next highest(2)
CSE DEPT. G RAJASEKHAR REDDY Page 86
C LANGUAGE
+,- lowest(1)
An algebraic expression can be represented using three different notations. They are infix, prefix and
postfix.
Infix: An operator is placed between the operands is called as infix expression
syntax: <operand><operator><operand>
Example: A+B
A-B*C
Prefix: An operator is placed before the operands is called as prefix notation or polish notation.
Syntax: <operator><operand><operand>
Example: + AB
*+AB-CD
Postfix: An operator is placed after the operands is called as postfix expression or reverse polish notation or
suffix notation.
Syntax: <operand><operand><operator>
Example: AB+
AB+CD-*
Stacks can be used to evaluate expressions and also to convert expressions from one form to another
form.
Conversion from infix to postfix: Procedure to convert from infix expression to postfix expression
is as follows:
First initialize stack to be empty.
If the scanned symbol is an operand, then place directly in the postfix expression (output).
If the scanned symbol is left parenthesis, push it onto the stack.
Else
If the stack is empty or the operator has highest priority than the operator which is on the
top of the stack or the top of the stack is opening parenthesis then push the operator on to
the stack.
Else
pop the operator from the stack and append to the output.
If the symbol scanned is a right parenthesis, pop the operators from the stack and append the
operators to the output until an opening parenthesis is encountered. pop the opening
parenthesis from the stack and discard it.
If the end of input string is encountered, then iterate the loop until the stack is not empty. pop
the stack and append the remaining input string to the output.
Precedence Values of Symbols in the Stack and Input for infix to postfix conversion
SYMBOL STACK PRECEDENCE INPUT PRECEDENCE
+,- 2 1
*,/,% 4 3
& or ^ 5 6
( 0 9
) 0
Example: consider the conversion of the infix expression, a*b/(c-d)+e*(f-g).to its equivalent
postfix notation.
Input string Stack Postfix notation
A Empty A
* * A
B * AB
/ / AB*
( /( AB*
C /( AB*C
- /(- AB*C
D /(- AB*CD
) / AB*CD-
+ + AB*CD-/
E + AB*CD-/E
* +* AB*CD-/E
( +*( AB*CD-/E
F +*( AB*CD-/EF
- +*(- AB*CD-/EF
G +*(- AB*CD-/EFG
) +* AB*CD-/EFG-
End of string The input is now empty. Pop the output AB*CD-/EFG-*+
symbols from the stack until it is empty.
Example: consider the conversion of the infix expression, ((A-(B+C))*D)^(E+F),to its
equivalent postfix notation.
Input string Stack Postfix notation
( (
( ((
A (( A
- ((- A
( ((-( A
B ((-( AB
+ ((-(+ AB
C ((-(+ ABC
) ((- ABC+
) ( ABC+-
* (* ABC+-
D (* ABC+-D
) EMPTY ABC+-D*
^ ^ ABC+-D*
( ^( ABC+-D*
E ^( ABC+-D*E
+ ^(+ ABC+-D*E
F ^(+ ABC+-D*EF
) ^ ABC+-D*EF+
End of string The input is now empty. Pop the output ABC+-D*EF+^
symbols from the stack until it is empty.
Example: consider the conversion of the infix expression, A+B*C-D/E*H,to its equivalent
postfix notation
Input string Stack Postfix notation
A EMPTY A
+ + A
B + AB
* +* AB
C +* ABC
- - ABC*+
D - ABC*+D
/ -/ ABC*+D
E -/ ABC*+DE
* -* ABC*+DE/
H -* ABC*+DE/H
End of string The input is now empty. Pop the output ABC*+DE/H*-
symbols from the stack until it is empty.
Example: convert the following expression (A*B)-(C*D) into its equivalent postfix notation
Input string Stack Postfix expression
( (
( ((
A (( A
* ((* A
B ((* AB
) ( AB*
- (- AB*
( (-( AB*
C (-( AB*C
* (-(,* AB*C
D (-(* AB*CD
) (- AB*CD*
) AB*CD*-
End of string The input is now empty. Pop the output AB*CD*-
symbols from the stack until it is empty.
Convert a + b * c + (d * e + f) * g the infix expression into postfix form.
Input string Stack Postfix expression
A A
+ + A
B + AB
* +* AB
C +* ABC
+ + ABC*+
( +( ABC*+
D +( ABC*+D
* +(* ABC*+D
E +(* ABC*+DE
+ +(+ ABC*+DE*
F +(+ ABC*+DE*F
) + ABC*+DE*F+
* +* ABC*+DE*F+
G +* ABC*+DE*F+G
End of string The input is now empty. Pop the output ABC*+DE*F+G*+
symbols from the stack until it is empty.
postfix[j]=infix[i];
j++;
}
else if(infix[i]=='+'||infix[i]=='-'||infix[i]=='*'||infix[i]=='/'||infix[i]=='%')
{
while((getpriority(stack[top])>=getpriority(infix[i])))
{
postfix[j]=pop(stack);
j++;
}
push(stack,infix[i]);
}
else if(infix[i]==')')
{
while((stack[top]!='('))
{
postfix[j]=pop(stack);
j++;
}
temp=pop(stack);
}
}
while((top!=-1))
{
postfix[j]=pop(stack);
j++;
}
postfix[j]='\0';
printf("postfix exp is:%s",postfix);
}
void push(char stack[],char element)
{
if(top==STACK_SIZE-1)
printf("stackoverflow:");
else
{
top++;
stack[top]=element;
}
}
char pop(char stack[])
{
charval;
if(top==-1)
printf("under flow:");
else
{
val =stack[top];
top--;
}
return val;
}
break;
case '^':res = pow(val1, val2);
break;
}
val_stack[top] = res;
}
else
val_stack[top] = ch-48; /*convert character digit to integer */
top++;
i++;
}
printf("\n Values of %s is : %f ",postfix, val_stack[0] );
getch();
}
Conversion from infix to prefix: Procedure to convert from infix expression to postfix expression is
as follows:
first initialize stack to be empty and reverse the given input string.
If the scanned symbol is an operand, append to the output.
If the scanned symbol is right parenthesis, push it onto the stack.
Else
If the stack is empty or the operator has highest priority than the operator which is on the top
of the stack or The top of the stack is right parenthesis, then push the operator on to the stack.
Else
pop the operator from the stack and append to the output.
If the symbol scanned is a left parenthesis, pop the operators from the stack and append the
operators to the output until the right parenthesis is encountered. Pop the right parenthesis
from the stack and discard it.
If the end of input string is encountered, then iterate the loop until the stack is not empty. Pop
the stack, and append the remaining input string to the output and reverse the output string.
Precedence Values of Symbols in the Stack and Input for infix to prefix conversion
SYMBOL STACK PRECEDENCE INPUT PRECEDENCE
+,- 1 2
*,/,% 3 4
& or ^ 6 5
( 0
) 0 9
Example: consider the conversion of the infix expression, A*B/(C-D)+E*(F-G),to its equivalent
prefix notation. First to convert infix expression to prefix expression, reverse the given input
string as follows: )G-F(*E+)D-C(/B*A
Input string Stack operation Prefix notation
) )
G ) G
- )- G
F )- GF
( EMPTY GF-
* * GF-
E * GF-E
+ + GF-E*
) +) GF-E*
D +) GF-E*D
- +)- GF-E*D
C +)- GF-E*DC
( + GF-E*DC-
/ +/ GF-E*DC-
B +/ GF-E*DC-B
* +/* GF-E*DC-B
A +/* GF-E*DC-BA
End of string The input is now empty. Pop the output GF-E*DC-BA*/+
symbols from the stack until it is empty.
Now, reverse the output string, GF-E*DC-BA*/+,as +/*AB-CD*E-FG to obtain the prefix notation.
Example: consider the conversion of the infix expression, A+B-C, to its equivalent prefix
notation. First to convert infix expression to prefix expression, reverse the given input string as
follows: c-b+a
Input string Stack operation Prefix notation
C Empty C
- - C
B - CB
+ -+ CB
A -+ CBA
End of string The input is now empty. Pop the output CBA+-
symbols from the stack until it is empty.
Now, reverse the output string, CBA+- as -+ABC to obtain the prefix notation
Example: consider the conversion of the infix expression,(A+B)*(C-D),to its equivalent prefix notation. First
to convert infix expression to prefix expression, reverse the given input string as follows:)D-C(*)B+A(
- )- D
C )- DC
( EMPTY DC-
* * DC-*
) *) DC-
B *) DC-B
+ *)+ DC-B
A *)+ DC-BA
( * DC-BA+
End of string The input is now empty. Pop the output DC-BA+*
symbols from the stack until it is empty.
Now, reverse the output string, DC-BA+* as *+AB-CD to obtain the prefix notation
Example: consider the conversion of the infix expression, A^B*C-D+E/F/(G+H),to its equivalent prefix
notation. First to convert infix expression to prefix expression, reverse the given input string as follows:
)H+G(/F/E+D-C*B^A.
{
if(op != ')')
{
while(lesspriority(op,opstack[top-1])==1&& top>0)
{
insert_beg(opstack[--top]);
}
}
opstack[top]=op; /* pushing onto stack */
top++;
}
}
void pop()
{
while(opstack[--top] != ')')
insert_beg(opstack[top]);
}
void main()
{
char ch;
int l, i = 0;
clrscr();
printf("\n Enter Infix Expression : ");
gets(infix);
l =strlen(infix);
while(l > 0)
{
ch = infix[--l];
switch(ch)
{
case ' ' : break;
case ')' :
case '+' :
case '-' :
case '*' :
case '/' :
case '^' :
case '%' :push(ch); /* check priority and push */
break;
case '(' :pop();
break;
default :insert_beg(ch);
}
}
while( top > 0 )
{
insert_beg(opstack[--top] );
j++;
}
prefix[j] = '\0';
printf("\n Infix Expression : %s ", infix);
printf("\n Prefix Expression : %s ", prefix);
getch();
}
Evaluation of prefix expression: stacks are also used to evaluate a prefix expression.to evaluate a
prefix expression, consider the following steps:
Reverse the given input string.
If the input string is an operand, then push it onto the stack.
If the input string is an operator, then the first two operands on the stack are evaluated using
this operator by popping them from the stack and the result is also placed onto the stack.
Example: consider the evaluation of a prefix expression, +/63*-432.to do this reverse the input
string as 234-*36/+
Character scanned Stack
2 2
3 2,3
4 2,3,4
- 2,1
* 2
3 2,3
6 2,3,6
/ 2,2
+ 4
Example: program for evaluation of prefix expression.
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#defineMax 20
int st[Max], top=-1;
void push(int ch)
{
if (top == Max-1)
printf("Stack is full\n");
else
{
top++;
st[top]=ch; }
}
int pop()
{
int ch;
if (top==-1)
printf("Stack is empty\n");
else
{
ch=st[top];
top--;
}
return ch;
}
void dispstack()
{
int k;
printf("stack Content: ");
for (k=top; k>=0; k--)
{
printf("%d, ", st[k]);
}
printf("\n");
}
int PreEval(char s[25])
{
char temp[25];
int i,val=0,ch1,ch2,j=0;
i=0; top=-1;
while (s[i]!='\0')
{*if operand is countered print it*/
if ( (s[i]>=48 && s[i]<=57) )
{
j=0;
temp[j]=s[i];
j++;
temp[j]='\0';
push(atoi(temp));
}
else
{
ch2=pop();
ch1=pop();
switch(s[i])
{
case '+' :{
val=ch2+ch1;
break;
}
case '-' :{
val=ch2-ch1;
break;
}
case '*' :{
val=ch2*ch1;
break;
}
case '/' :{
val=ch2/ch1;
break;
}
}
push(val);
}
i++;
}
val=pop();
return val;
}
void main()
{
char s[25],s1[25];
int val;
clrscr();
printf("enter a Prefix expression for evaluation\n");
scanf("%s",s);
strcpy(s1,strrev(s));
val= PreEval(s1);
printf("Value of Prefix Expression=%d\n", val);
getch();
}
Conversion from postfix to infix: Procedure to convert postfix expression to infix expression is as
follows:
Scan the postfix expression from left to right.
If the scanned symbol is an operand, then push it onto the stack.
If the scanned symbol is an operator, pop two symbols from the stack and create it as a string
by placing the operator in between the operands and push it onto the stack.
Repeat steps 2 and 3 till the end of the expression.
Example: Convert the following postfix expression A B C * D E F ^ / G * - H * + into its
Equivalent infix expression
pop(str2);
temp[0] ='(';
temp[1] ='\0';
strcpy(str, temp);
strcat(str, str2);
temp[0] = s[i];
temp[1] = '\0';
strcat(str,temp);
strcat(str, str1);
temp[0] =')';
temp[1] ='\0';
strcat(str,temp);
push(str);
}
else
{
temp[0]=s[i];
temp[1]='\0';
strcpy(s1, temp);
push(s1);
}
i++;
}
printf("\nThe Infix expression is: %s", stack[0]);
}
void pop(char *a1)
{
strcpy(a1,stack[top]);
top--;
}
void push (char*str)
{
if(top==MAX-1)
printf("\nstack is full");
else
{
top++;
strcpy(stack[top], str);
}
}
Conversion from postfix to prefix: Procedure to convert postfix expression to prefix expression is
as follows:
Scan the postfix expression from left to right.
If the scanned symbol is an operand, then push it onto the stack.
If the scanned symbol is an operator, pop two symbols from the stack and create it as a string
by placing the operator in front of the operands and push it onto the stack.
Repeat steps 2 and 3 till the end of the expression.
Example: Convert the following postfix expression A B C * D E F ^ / G * - H * + into its
equivalent prefix expression.
CSE DEPT. G RAJASEKHAR REDDY Page 103
C LANGUAGE
strcat(str, str1);
push(str);
}
else
{
temp[0] = s[i];
temp[1] = '\0';
strcpy (s1, temp);
push (s1);
}
i++;
}
printf("\n The prefix expression is: %s", stack[0]);
}
void pop(char*a1)
{
if(top==-1)
{
printf("\nStack is empty");
}
else
{
strcpy (a1, stack[top]);
top--;
}
}
void push (char *str)
{
if(top==MAX-1)
printf("\nstack is full");
else
{
top++;
strcpy(stack[top], str);
}
}
Conversion from prefix to infix: Procedure to convert prefix expression to infix expression is as
follows:
Scan the prefix expression from right to left (reverse order).
If the scanned symbol is an operand, then push it onto the stack.
If the scanned symbol is an operator, pop two symbols from the stack and create it as a
string by placing the operator in between the operands and push it onto the stack.
Repeat steps 2 and 3 till the end of the expression.
Example: Convert the following prefix expression + A * - * B C * / D ^ E F G H into its equivalent
infix expression.
temp[1] = '\0';
strcat(str,temp);
strcat(str, str2);
temp[0] =')';
temp[1] ='\0';
strcat(str,temp);
push(str);
}
else
{
temp[0]=s[i];
temp[1]='\0';
strcpy(s1, temp);
push(s1);
}
i++;
}
printf("\nThe infix expression is: %s", stack[0]);
}
void pop(char *a1)
{
strcpy(a1,stack[top]);
top--;
}
void push (char*str)
{
if(top==MAX - 1)
printf("\nstack is full");
else
{
top++;
strcpy(stack[top], str);
}
}
Conversion from prefix to postfix: Procedure to convert prefix expression to postfix expression is
as follows:
Scan the prefix expression from right to left (reverse order).
If the scanned symbol is an operand, then push it onto the stack.
If the scanned symbol is an operator, pop two symbols from the stack and create it as a string
by placing the operator after the operands and push it onto the stack.
Repeat steps 2 and 3 till the end of the expression.
Example: Convert the following prefix expression + A * - * B C * / D ^ E F G H into its
equivalent postfix expression.
temp[0] = s[i];
temp[1] = '\0';
strcat(str1,str2);
strcat (str1, temp);
strcpy(str, str1);
push(str);
}
else
{
temp[0] = s[i];
temp[1] = '\0';
strcpy (s1, temp);
push (s1);
}
i++;
}
printf("\nThe postfix expression is: %s", stack[0]);
}
void pop(char*a1)
{
if(top == -1)
printf("\nStack is empty");
else
{
strcpy (a1, stack[top]);
top--;
}
}
void push (char *str)
{
if(top == MAX - 1)
printf("\nstack is full");
else
{
top++;
strcpy(stack[top], str);
}
}
UNIT-IV
QUEUES
Queue (linear data structure): Queue is an ordered set of homogeneous elements, where items are
inserted at one end called the rear and deleted at the other end called the front. Queue follows the
principle First in First out (FIFO), in which first element inserted into the queue will be the first
element to be deleted from the queue.
Ex: Ticket reservation counter, Waiting line in a supermarket, a bank etc.
Operations on queues: The two basic operations performed on queue are
enqueue (Insertion, adding, write)
dequeue (Deletion, removing, read)
CSE DEPT. G RAJASEKHAR REDDY Page 109
C LANGUAGE
Enqueue: Adding an element to the queue is called enqueue operation.an element can be inserted
into the queue only when the queue is empty or when the queue is not full. Before inserting an
element into the queue, check whether the queue is full or not. If the queue is not full, insert the
element into the queue. Otherwise insertion is not possible and this situation leads to overflow
condition. Inserting an element into a queue will be done at REAR end. If we want to insert an
element into a queue then REAR value is incremented by “one (1)”. i.e. REAR=REAR+1;
The precondition associated with enqueue operation is queue overflow i.e. Trying to insert an
element when the queue is full (REAR==QUEUE_SIZE-1)
Algorithm:
Step 1: If REAR=QUEUE-SIZE-1then print “Queue is full” else goto step2
Step 2: REAR =REAR +1
Queue [REAR]= element
Dequeue: Deleting an element from the queue is called as dequeue operation. An element can be
removed from the queue only when the queue is not empty. Before removing an element from the
queue, check whether the queue is empty or not. If the queue is not empty the remove operation can
be done at the front end of the queue. Otherwise deletion is not possible. Deleting an element from
the queue is done at FRONT end. If we want to delete an element from the queue the FRONT value
is incremented by “one”.i.e front=front+1
The precondition associated with dequeue operation is underflow i.e., Trying to delete an element
when the queue is empty (FRONT= =REAR)
Algorithm:
Step 1: If front==REAR then print” Queue is empty” else goto step2
Step 2: FRONT FRONT+1
print queue [FRONT]
#include<stdio.h>
#define QUEUE_SIZE 4
int queue[QUEUE_SIZE];
int front=-1,rear=-1;
void enqueue(int);
void dequeue();
void display();
void main()
{
int ch,ele;
clrscr();
while(1)
{
printf("\n\n-----options----\n\n");
printf("1.enqueue\n2.dequeue\n3.display\n4.exit\n");
printf("enter your choice\n");
scanf("%d", &ch);
switch(ch)
{
case 1: printf("enter the element to inserted:");
scanf("%d", &ele);
enqueue(ele);
break;
case 2: dequeue();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("invalid choice\n");
}
}
}
void enqueue(int ele)
{
if(rear= =QUEUE_SIZE-1)
printf("\nqueue is overflow");
else
{
rear = rear+1;
queue[rear]=ele;
}
}
void dequeue()
{
if(front==rear)
printf("queue is underflow\n");
else
{
front=front+1;
printf("deleted element is:%d",queue[front]);
if(front==rear)
front=rear=-1;
}
}
void display()
{
int i;
if(front==rear)
printf(" \n queue is empty ");
else
{
for(i=front+1; i<= rear; i++)
printf("%5d", queue[i]);
}
}
Example: Write a c program which implements queue operations(wnen front=rear=0).
a) enqueue b) dequeue c) display
# include <conio.h>
# define MAX 6
int Q[MAX];
int front, rear;
void insertQ()
{
int data;
if(rear == MAX)
printf("\n Linear Queue is full");
else
{
printf("\n Enter data: ");
scanf("%d", &data);
Q[rear] = data;
rear++;
printf("\n Data Inserted in the Queue ");
}
}
void deleteQ()
{
if(rear == front)
printf("\n\n Queue is Empty..");
else
{
printf("\n Deleted element from Queue is %d", Q[front]);
front++;
if(front=rear)
front=rear=0;
}
}
void displayQ()
{
int i;
if(front == rear)
printf("\n\n\t Queue is Empty");
else
{
printf("\n Elements in Queue are: ");
for(i = front; i < rear; i++)
printf("%d\t", Q[i]);
}
}
int menu()
{
int ch;
clrscr();
printf("\n \tQueue operations using ARRAY..");
printf("\n -----------**********-------------\n");
printf("\n 1. Insert ");
printf("\n 2. Delete ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
scanf("%d", &ch);
return ch;
}
void main()
{
int ch;
do
{
ch = menu();
switch(ch)
{
case 1:insertQ();
break;
case 2: deleteQ();
break;
case 3:displayQ();
break;
case 4:exit(0);
}
} while(1);
}
Applications of Queue:
It is used to schedule the jobs to be processed by the CPU.
When multiple users send print jobs to a printer, each printing job is kept in the printing
queue. Then the printer prints those jobs according to first in first out (FIFO) basis.
Breadth first search uses a queue data structure to find an element from a graph.
In real life, Call Center phone systems will use Queues, to hold people calling them in an
order, until a service representative is free.
Circular Queue: In linear queues, insertion can be done only at one end called rear deletions are
always done from the other end called the front.
Example:
10 20 30 40
Front=-1 Rear=3
Now, in the above example if we want to insert another value, it is not possible because the queue is
completely full. i.e there is no empty space where the value can be inserted.
Consider a case in which two successive deletions are made. Then the queue looks as follows:
30 40
Front=1 Rear=3
Now if want to insert a new element (suppose it as 50) in the queue, it fails even though there is
space available, the overflow condition still exists because the condition rear = queue_size-1 still
holds true. This is a major drawback of a linear queue.
To resolve this problem, we have two solutions:
Shift the elements to the left so that the vacant space can be occupied and utilized efficiently. But
this can be very time –consuming, especially when the queue is large.
To use a circular queue. In circular queue, the first index comes right after the last index.
Circular queue is a linear data structure, where the elements are inserted at one end called rear and
elements are deleted at another end called front. Circular queue follows first in first out (FIFO)
principle. In circular queue the last node is connected back to the first node to make a circle. In a
circular queue the insertion of an element can be done even when rear is equal to the maximum size
of a queue, when the space is available at front of the (beginning) queue. Both “front” and “rear”
move in a clockwise direction over the queue. But logically in a circular queue the first element
comes after the last element. A circular queue is implemented in the same manner as a linear queue is
implemented.
Operations on circular queues: The two basic operations performed on queue are
enqueue (Insertion, adding, write)
dequeue (Deletion, removing, read)
Enqueue: Adding an element to the circular queue is called enqueue operation.an element can be
inserted into the circular queue only when the circular queue is empty or when the circular queue is
not full. Before inserting an element into the circular queue, check whether the circular queue is full
or not. If the circular queue is not full, insert the element into the circular queue. Otherwise insertion
is not possible and this situation leads to overflow condition. Inserting an element into a circular
queue will be done at REAR end. If we want to insert an element into a circular queue then REAR
value is incremented by “one (1)”. i.e. REAR=REAR+1;
The precondition associated with enqueue operation is queue overflow i.e. Trying to insert an
element when the queue is full (((REAR==QUEUE_SIZE-1)&& front==-1))|| ((front==rear) &&
(front != -1)))
Algorithm for enqueue operation:
Step 1: If REAR=QUEUE-SIZE-1then print “Queue is full” else goto step2
Step 2: REAR =REAR +1
Queue [REAR]= element
dequeue: Deleting an element from the circular queue is called as dequeue operation. An element
can be removed from the circular queue only when the circular queue is not empty. Before removing
an element from the circular queue, check whether the circular queue is empty or not. If the circular
queue is not empty the remove operation can be done at the front end of the circular queue.
Otherwise deletion is not possible. Deleting an element from the circular queue is done at FRONT
end. If we want to delete an element from the queue the FRONT value is incremented by “one”.i.e
front=front+1
The precondition associated with dequeue operation is underflow i.e., Trying to delete an element
when the queue is empty ((front = = rear) && (front = = -1))
Algorithm for dequeue operation :
Step 1: If front==REAR then print” Queue is empty” else goto step2
Step 2: FRONT FRONT+1
print queue [FRONT]
#include<stdio.h>
#define QUEUE_SIZE 4
int queue[QUEUE_SIZE];
int front= -1,rear= -1;
void enqueue(int);
void dequeue();
void display();
void main()
{
int ch,ele;
clrscr();
while(1)
{
printf("\n\n-----options----\n\n");
printf("1.enqueue\n2.dequeue\n3.display\n4.exit\n");
printf("enter your choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1: printf("enter the element to inserted:");
scanf("%d",&ele);
enqueue(ele);
break;
case 2: dequeue();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("invalid choice\n");
}
}
}
void enqueue(int ele)
{
if(((rear==QUEUE_SIZE-1) && (front==-1))||((front==rear)&&(front!= -1)))
printf("\nqueue is overflow");
else if((rear = = QUEUE_SIZE-1) && (front != -1))
{
rear=0;
queue[rear] = ele;
}
else
{
rear = rear+1;
queue[rear] = ele;
}
}
void dequeue()
{
if((front = = rear) && (front = = -1))
printf("queue is underflow\n");
else
{
if(front = = QUEUE_SIZE-1)
front = -1;
front = front+1;
printf("deleted element is:%d",queue[front]);
if(front = = rear)
front = rear = -1;
}
}
void display()
{
int i;
if((front = = rear) && (front = = -1))
printf("\n queue is empty");
else
{
if(front<rear)
{
for(i=front+1; i<=rear; i++)
printf("%5d", queue[i]);
}
else
{
for(i=0; i<=rear; i++)
printf("%5d",queue[i]);
for(i=front+1; i<=QUEUE_SIZE-1; i++)
printf("%5d",queue[i]);
}
}
}
Example: Write a C program to implement a circular queue operations.
a) enqueue b)dequeue c) display
#include <stdio.h>
#include <conio.h>
#define MAX 6
int CQ[MAX];
int front = 0;
int rear = 0;
int count = 0;
void insertCQ()
{
int data;
if(count == MAX)
{
printf("\n Circular Queue is Full");
}
else
{
printf("\n Enter data: ");
scanf("%d", &data);
CQ[rear] = data;
rear = (rear + 1) % MAX;
count ++;
printf("\n Data Inserted in the Circular Queue ");
}
}
void deleteCQ()
{
if(count == 0)
{
printf("\n\nCircular Queue is Empty..");
}
else
{
printf("\n Deleted element is %d ", CQ[front]);
front = (front + 1) % MAX;
count --;
}
}
void displayCQ()
{
int i, j;
if(count == 0)
printf("\n\n\t Circular Queue is Empty ");
else
{
printf("\n Elements in Circular Queue are: ");
j = count;
for(i = front; j!= 0; j--)
{
printf("%d\t", CQ[i]);
i = (i + 1) % MAX;
}
}
}
int menu()
{
int ch;
clrscr();
printf("\n \t Circular Queue Operations using ARRAY..");
printf("\n -----------**********-------------\n");
printf("\n 1. Insert ");
printf("\n 2. Delete ");
CSE DEPT. G RAJASEKHAR REDDY Page 124
C LANGUAGE
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter Your Choice: ");
scanf("%d", &ch);
return ch;
}
void main()
{
int ch;
do
{
ch = menu();
switch(ch)
{
case 1: insertCQ();
break;
case 2: deleteCQ();
break;
case 3: displayCQ();
break;
case 4:return;
default: printf("\n Invalid Choice ");
}
} while(1);
}
Deque:In the preceding section we saw that a queue in which we insert items at one end and from
which we remove items at the other end. In this section we examine an extension of the queue, which
provides a means to insert and remove items at both ends of the queue. This data structure is a deque.
The word deque is an acronym derived from double-ended queue. Figure 4.5 shows the
representation of a deque.
A deque provides four operations. Figure 4.6 shows the basic operations on a deque.
• enqueue_front: insert an element at front.
• dequeue_front: delete an element at front.
• enqueue_rear: insert element at rear.
• dequeue_rear: delete element at rear.
Linked lists have their own strengths and weaknesses, but they happen to be strong where arrays are
weak. Generally array's allocates the memory for all its elements in one block whereas linked lists
use an entirely different strategy. Linked lists allocate memory for each element separately and only
when necessary.
Linked List Concepts: A linked list is a non-sequential collection of data items. It is a dynamic data
structure. For every data item in a linked list, there is an associated pointer that would give the
memory location of the next data item in the linked list. The data items in the linked list are not in
consecutive memory locations. They may be anywhere, but the accessing of these data items is easier
as each data item contains the address of the next data item.
Advantages of linked lists: Linked lists have many advantages. Some of the very important
advantages are:
1. Linked lists are dynamic data structures. i.e., they can grow or shrink during the execution of a
program.
2. Linked lists have efficient memory utilization. Here, memory is not pre-allocated. Memory is
allocated whenever it is required and it is de-allocated (removed) when it is no longer needed.
3. Insertion and Deletions are easier and efficient. Linked lists provide flexibility in inserting a
data item at a specified position and deletion of the data item from the given position.
4. Many complex applications can be easily carried out with linked lists.
Single linked list: A linked list allocates space for each element separately in its own block of
memory called a "node". The list gets an overall structure by using pointers to connect all its nodes
together like the links in a chain. Each node contains two fields; a "data" field to store whatever
element, and a "next" field which is a pointer used to link to the next node. Each node is allocated in
the heap using malloc(), so the node memory continues to exist until it is explicitly de-allocated
using free(). The front of the list is a pointer to the “start” node.
The beginning of the linked list is stored in a "start" pointer which points to the first node. The first
node contains a pointer to the second node. The second node contains a pointer to the third node, and
so on. The last node in the list has its next field set to NULL to mark the end of the list. Code can
access any node in the list by starting at the start and following the next pointers.
The start pointer is an ordinary local pointer variable, so it is drawn separately on the left top to show
that it is in the stack. The list nodes are drawn on the right to show that they are allocated in the heap.
Implementation of Single Linked List: Before writing the code to build the above list, we need to
create a start node, used to create and access other nodes in the linked list. The following structure
definition will do
• Creating a structure with one data item and a next pointer, this will be pointing to next
Creating a node for Single Linked List: Creating a singly linked list starts with creating a node.
Sufficient memory has to be allocated for creating a node. The information is stored in the memory,
allocated by using the malloc() function. The function getnode(), is used for creating a node, after
allocating memory for the structure of type node, the information for the item (i.e., data) has to be
read from the user, set next field to NULL and finally returns the address of the node.
Creation of a node for single linked list:
Creating a Singly Linked List with ‘n’ number of nodes: The following steps are to be followed
to create ‘n’ number of nodes:
• Get the new node using getnode().
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;
• If the list is not empty, then
temp=start;
while(temp->next!=NULL)
newnode = getnode();
• If the list is empty then start = newnode.
• If the list is not empty, follow the steps given below:
newnode -> next = start;
start = newnode;
The following diagram shows inserting a node into the single linked list at the beginning
The function insert_at_mid(), is used for inserting a node in the intermediate position.
void insert_at_mid()
{
node *newnode, *temp, *prev;
Deleting a node at the beginning: The following steps are followed, to delete a node at the
beginning of the list:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
start = temp -> next;
free(temp);
The below Figure shows deleting a node at the beginning of a single linked list.
The function delete_at_beg(), is used for deleting the first node in the list.
void delete_at_beg()
{
CSE DEPT. G RAJASEKHAR REDDY Page 133
C LANGUAGE
node *temp;
if(start == NULL)
{
printf("\n No nodes are exist..");
return ;
}
else
{
temp = start;
start = temp -> next;
free(temp);
printf("\n Node deleted ");
}
}
Deleting a node at the end: The following steps are followed to delete a node at the end of the list:
If list is empty then display ‘Empty List’ message.
If the list is not empty, follow the steps given below:
temp = prev = start;
while(temp -> next != NULL)
{
prev = temp;
temp = temp -> next;
}
prev -> next = NULL;
free(temp);
The below Figure shows deleting a node at the end of a single linked list.
The function delete_at_last(), is used for deleting the last node in the list.
void delete_at_last()
{
node *temp, *prev;
if(start == NULL)
{
printf("\n Empty List..");
return ;
}
else
{
temp = start;
prev = start;
while(temp -> next != NULL)
{
prev = temp;
temp = temp -> next;
}
prev -> next = NULL;
free(temp);
printf("\n Node deleted ");
}
}
Deleting a node at Intermediate position: The following steps are followed, to delete a node from
an intermediate position in the list (List must contain more than two node).
If list is empty then display ‘Empty List’ message
If the list is not empty, follow the steps given below.
if(pos > 1 && pos < nodectr)
{
temp = prev = start;
ctr = 1;
while(ctr < pos)
{
prev = temp;
temp = temp -> next;
ctr++;
}
prev -> next = temp -> next;
free(temp);
printf("\n node deleted..");
}
The below Figure shows deleting a node at a specified intermediate position other than beginning
and end from a single linked list.
The function delete_at_mid(), is used for deleting the intermediate node in the list.
CSE DEPT. G RAJASEKHAR REDDY Page 135
C LANGUAGE
void delete_at_mid()
{
int ctr = 1, pos, nodectr;
node *temp, *prev;
if(start == NULL)
{
printf("\n Empty List..");
return ;
}
else
{
printf("\n Enter position of node to delete: ");
scanf("%d", &pos);
nodectr = countnode(start);
if(pos > nodectr)
printf("\nThis node doesnot exist");
if(pos > 1 && pos < nodectr)
{
temp = prev = start;
while(ctr < pos)
{
prev = temp;
temp = temp -> next;
ctr ++;
}
prev -> next = temp -> next;
free(temp);
printf("\n Node deleted..");
}
else
printf("\n Invalid position..");
getch();
}
}
Display: To display the information, we need to check whether the list is empty or not. If the list is
not empty, you have to move through a linked list, node by node from the first node, until the end of
the list is reached. Displaying a list involves the following steps:
Assign the address of start pointer to a temp pointer.
Display the information from the data field of each node.
The function display() is used for displaying the information stored in the list from left to right.
void display()
{
node *temp;
temp = start;
printf("\n The contents of List (Left to Right): \n");
if(start == NULL )
printf("\n Empty List");
else
{
while (temp != NULL)
CSE DEPT. G RAJASEKHAR REDDY Page 136
C LANGUAGE
{
printf("%d ->", temp -> data);
temp = temp -> next;
}
}
}
Traverse: To display the information, you have to traverse the list through a linked list, node by
node from the first node, until the end of the list is reached. The function traverse() is used to
traverse and Display the elements in the list. Traversing a list involves the following steps
Assign the address of start pointer to a temp pointer.
Display the information from the data field of each node.
The function traverse() is used for traverse and display the information stored in the list from
left to right.
void traverse()
{
node *temp;
temp = start;
printf("\n The contents of List (Left to Right): \n");
if(start == NULL )
printf("\n Empty List");
else
{
while (temp != NULL)
{
printf("%d ->", temp -> data);
temp = temp -> next;
}
}
}
Searching a node in linked list: The search function attempts to locate the requested element in the linked list. If
the node in the list matches with key, the search returns true if no key matches, it returns false. The function
given below searches through the linked list and returns a pointer the first occurrence of the search key or
returns NULL pointer if the search key is not in the list
Searching a node in linked list involves the following steps
Take pointer variable temp which points to START
Move temp which points to NULL
If data part of temp is equals to key then return true otherwise return NULL
The function searching() is used for searching the key element in the linked list .
void search()
{
node *temp;
int key;
printf("enter key to be searched");
scanf("%d",&key);
if(start == NULL)
CSE DEPT. G RAJASEKHAR REDDY Page 137
C LANGUAGE
printf("list is empty");
temp=start;
while(temp!=NULL)
{
if(key==temp->data)
{
printf("search is successful");
return;
}
temp=temp->next;
}
if(temp==NULL)
printf("search is unsuccessful");
}
Counting the Number of Nodes: The following code will count the number of nodes exist in the list
using recursion.
int countnode(node *st)
{
if(st == NULL)
return 0;
else
return(1 + countnode(st->next));
}
Example: Write a c program which implements Single Linked List operations using linked list
a) Insert b) delete c) display d) search
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct slinklist
{
int data;
struct slinklist *next;
};
typedef struct slinklist node;
node *start = NULL;
int menu()
{
int ch;
clrscr();
printf("\n 1.Create a list ");
printf("\n--------------------------");
printf("\n 2.Insert a node at beginning ");
printf("\n 3.Insert a node at end");
printf("\n 4.Insert a node at middle");
printf("\n--------------------------");
printf("\n 5.Delete a node from beginning");
printf("\n 6.Delete a node from Last");
printf("\n 7.Delete a node from Middle");
printf("\n--------------------------");
printf("\n 8.display the list");
printf("\n--------------------------");
printf("\n 9.searching");
printf("\n--------------------------");
printf("\n 10. Count nodes ");
printf("\n--------------------------");
printf("\n 11. Exit ");
printf("\n\n Enter your choice: ");
scanf("%d",&ch);
return ch;
}
node* getnode()
{
node *newnode;
newnode=(node *) malloc(sizeof(node));
printf("\n Enter data: ");
scanf("%d", &newnode -> data);
newnode -> next = NULL;
return newnode;
}
int countnode(node *ptr)
{
int count=0;
while(ptr!= NULL)
{
count++;
ptr = ptr -> next;
}
return count;
}
void createlist(int n)
{
int i;
node *newnode;
node *temp;
for(i = 0; i < n; i++)
{
newnode = getnode();
if(start == NULL)
start = newnode;
else
{
temp = start;
while(temp -> next != NULL)
temp = temp -> next;
temp -> next = newnode;
}
}
}
void display()
{
node *temp;
temp = start;
printf("\n The contents of List (Left to Right): \n");
if(start == NULL)
prev = temp;
temp = temp -> next;
}
prev -> next = NULL;
free(temp);
printf("\n Node deleted ");
}
}
void delete_at_mid()
{
int ctr = 1, pos, nodectr;
node *temp, *prev;
if(start == NULL)
printf("\n Empty List..");
else
{
printf("\n Enter position of node to delete: ");
scanf("%d", &pos);
nodectr = countnode(start);
if(pos > nodectr)
printf("\nThis node doesnot exist");
if(pos > 1 && pos < nodectr)
{
temp = prev = start;
while(ctr < pos)
{
prev = temp;
temp = temp -> next;
ctr++;
}
prev -> next = temp -> next;
free(temp);
printf("\n Node deleted..");
}
else
printf("\n Invalid position..");
}
}
void main()
{
int ch, n;
clrscr();
while(1)
{
ch = menu();
switch(ch)
{
case 1:if(start == NULL)
{
printf("\n Number of nodes you want to create: ");
scanf("%d", &n);
createlist(n);
Implementation of double linked list: Before implementing the double linked list, we have to
create start pointer, by which we can access and create other nodes. The beginning of the double
linked list is stored in a "start" pointer which points to the first node. The first node’s left link and
last node’s right link is set to NULL.
The following code gives the structure definition:
Creating a node for Double Linked List: Creating a double linked list starts with creating a node.
Sufficient memory has to be allocated for creating a node. The information is stored in the memory,
allocated by using the malloc() function. The function getnode(), is used for creating a node, after
allocating memory for the structure of type node, the information for the item (i.e., data) has to be
read from the user and set left field to NULL and right field also set to NULL
Creating a Double Linked List with ‘n’ number of nodes: The following steps are to be followed
to create ‘n’ number of nodes:
• Get the new node using getnode().
newnode =getnode();
• If the list is empty then start = newnode.
• If the list is not empty, follow the steps given below:
• The left field of the new node is made to point the previous node.
• The previous nodes right field must be assigned with address of the new node.
• Repeat the above steps ‘n’ times.
The function createlist(), is used to create ‘n’ number of nodes:
void createlist( int n)
{
int i;
no de * newno de;
no de *temp;
for( i = 0; i < n; i++)
{
newno de = getno de();
if(start == NULL)
start = newno de;
els e
{
temp = start;
while(temp -> r ight)
temp = temp -> r ight;
temp -> r ight = newno de;
newno de -> left = temp;
}
}
}
The below Figure shows 3 items in a double linked list stored at different locations
Inserting a node at the beginning: The following steps are to be followed to insert a new node at
the beginning of the list:
• Get the new node using getnode().
newnode=getnode();
• If the list is empty then start = newnode.
• If the list is not empty, follow the steps given below:
newnode -> right = start;
start -> left = newnode;
start = newnode;
The below Figure shows inserting a node into the double linked list at the beginning.
The below Figure shows inserting a node into the double linked list at the end.
The function dbl_insert_mid(), is used for inserting a node in the intermediate position.
void dll_insert_mid()
{
node *newnode,*temp;
int pos, nodectr, ctr = 1;
newnode = getnode();
printf("\n Enter the position: ");
scanf("%d", &pos);
nodectr = countnode(start);
if(pos - nodectr >= 2)
{
printf("\n Position is out of range..");
return;
}
if(pos > 1 && pos < nodectr)
{
temp = start;
while(ctr < pos - 1)
{
temp = temp -> right;
ctr++;
}
newnode -> left = temp;
newnode -> right = temp -> right;
temp -> right -> left = newnode;
temp -> right = newnode;
}
else
printf("position %d of list is not a middle position ", pos);
}
Deleting a node at the beginning: The following steps are followed, to delete a node at the
beginning of the list:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
start = start -> right;
start -> left = NULL;
free(temp);
The below Figure shows deleting a node at the beginning of a double linked list.
The function dbl_delete_beg(), is used for deleting the first node in the list.
void dll_delete_beg()
{
node *temp;
if(start == NULL)
{
printf("\n Empty list");
return ;
}
else
{
temp = start;
start = start -> right;
start -> left = NULL;
free(temp);
}
}
Deleting a node at the end: The following steps are followed to delete a node at the end of the list:
• If list is empty then display ‘Empty List’ message
• If the list is not empty, follow the steps given below:
temp = start;
while(temp -> right != NULL)
temp = temp -> right;
temp -> left -> right = NULL;
free(temp);
The below Figure shows deleting a node at the end of a double linked list.
The function dbl_delete_last(), is used for deleting the last node in the list.
void dll_delete_last()
{
node *temp;
if(start == NULL)
{
printf("\n Empty list");
return ;
}
else
{
temp = start;
while(temp -> right != NULL)
temp = temp -> right;
temp -> left -> right = NULL;
free(temp);
temp = NULL;
}
}
Deleting a node at Intermediate position: The following steps are followed, to delete a node from
an intermediate position in the list (List must contain more than two nodes).
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
• Get the position of the node to delete.
• Ensure that the specified position is in between first node and last node. If not, specified
position is invalid.
• Then perform the following steps:
if(pos > 1 && pos < nodectr)
{
temp = start;
i = 1;
while(i < pos)
{
temp = temp -> right;
i++;
}
temp -> right -> left = temp -> left;
temp -> left -> right = temp -> right;
free(temp);
printf("\n node deleted..");
}
The below Figure shows deleting a node at a specified intermediate position other than beginning
and end from a double linked list.
The function delete_at_mid(), is used for deleting the intermediate node in the list.
void dll_delete_mid()
{
int i = 0, pos, nodectr;
node *temp;
if(start == NULL)
printf("\n Empty List");
else
{
printf("\n Enter the position of the node to delete: ");
scanf("%d", &pos);
nodectr = countnode(start);
if(pos > nodectr)
{
printf("\nthis node does not exist");
return;
}
if(pos > 1 && pos < nodectr)
{
temp = start;
i = 1;
while(i < pos)
{
temp = temp -> right;
i++;
}
temp -> right -> left = temp -> left;
temp -> left -> right = temp -> right;
free(temp);
printf("\n node deleted..");
}
else
{
printf("\n It is not a middle position..");
}
}
}
Display: To display the information, you have to traverse the list, node by node from the first node,
until the end of the list is reached. The function display() is used for displaying the information
stored in the list from left to right and/or right to left.
Procedure for displaying information from left to right:
}
while(temp != NULL)
{
printf("\t%d", temp -> data);
temp = temp -> left;
}
}
Traversal and displaying a list (left to right): To display the information, you have to traverse the
list, node by node from the first node, until the end of the list is reached. The function
traverse_left_right() is used for traversing and displaying the information stored in the list from left
to right.The following steps are followed, to traverse a list from left to right:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
while(temp != NULL)
{
print temp -> data;
temp = temp -> right;
}
The function void traverse_left_to_right() is used to traverse the list from left to right
void traverse_left_to_right()
{
node *temp;
temp = start;
printf("\n The contents of List: ");
if(start == NULL )
printf("\n Empty List");
else
{
while(temp != NULL)
{
printf("\t %d ", temp -> data);
temp = temp -> right;
}
}
}
Traversal and displaying a list (Right to Left):To display the information from right to left, you
have to traverse the list, node by node from the first node, until the end of the list is reached. The
function traverse_right_left() is used for traversing and displaying the information stored in the list
from right to left. The following steps are followed, to traverse a list from right to left:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
Counting the Number of Nodes: The following code will count the number of nodes exist in the list
(using recursion).
int countno de(no de *start)
{
if(start == NULL)
return 0;
els e
return(1 + co untno de(start ->r ight ));
}
Example: Write a c program which Implements Double Linked List operations using linked
list.
a) insert b) delete c) display d)traverse e)search
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct dlinklist
{
struct dlinklist *left;
int data;
struct dlinklist *right;
};
typedef struct dlinklist node;
CSE DEPT. G RAJASEKHAR REDDY Page 154
C LANGUAGE
newnode = getnode();
if(start == NULL)
start = newnode;
else
{
temp = start;
while(temp -> right)
temp = temp -> right;
temp -> right = newnode;
newnode -> left = temp;
}
}
}
void display_right_to_left()
{
node *temp;
temp = start;
printf("\n The contents of List: ");
if(start == NULL)
printf("\n Empty List");
else
{
while(temp -> right != NULL)
temp = temp -> right;
}
while(temp != NULL)
{
printf("\t<--%d", temp -> data);
temp = temp -> left;
}
}
void traverse_left_to_right()
{
node *temp;
temp = start;
printf("\n The contents of List: ");
if(start == NULL )
printf("\n Empty List");
else
{
while(temp != NULL)
{
printf("\t %d--> ", temp -> data);
temp = temp -> right;
}
}
}
void display_left_to_right()
{
node *temp;
temp = start;
printf("\n The contents of List: ");
if(start == NULL )
printf("\n Empty List");
else
{
while(temp != NULL)
{
printf("\t %d--> ", temp -> data);
temp = temp -> right;
}
}
}
void traverse_right_to_left()
{
node *temp;
temp = start;
printf("\n The contents of List: ");
if(start == NULL)
printf("\n Empty List");
else
{
while(temp -> right != NULL)
temp = temp -> right;
}
while(temp != NULL)
{
printf("\t<--%d", temp -> data);
temp = temp -> left;
}
}
void dll_insert_beg()
{
node *newnode;
newnode = getnode();
if(start == NULL)
start = newnode;
else
{
newnode -> right = start;
start -> left = newnode;
start = newnode;
}
}
void dll_insert_end()
{
node *newnode, *temp;
newnode = getnode();
if(start == NULL)
start = newnode;
else
{
temp = start;
while(temp -> right != NULL)
node *temp;
if(start == NULL)
{
printf("\n Empty list");
return ;
}
else
{
temp = start;
while(temp -> right != NULL)
temp = temp -> right;
temp -> left -> right = NULL;
free(temp);
temp = NULL;
}
}
void dll_delete_mid()
{
int i = 0, pos, nodectr;
node *temp;
if(start == NULL)
{
printf("\n Empty List");
return;
}
else
{
printf("\n Enter the position of the node to delete: ");
scanf("%d", &pos);
nodectr = countnode(start);
if(pos > nodectr)
{
printf("\nthis node does not exist");
return;
}
if(pos > 1 && pos < nodectr)
{
temp = start;
i = 1;
while(i < pos)
{
temp = temp -> right;
i++;
}
temp -> right -> left = temp -> left;
temp -> left -> right = temp -> right;
free(temp);
printf("\n node deleted..");
}
else
{
printf("\n It is not a middle position..");
}
}
}
void search()
{
int key;
node *temp;
printf("\nenter key to be searched");
scanf("%d",&key);
if(start==NULL)
printf("list is empty");
temp=start;
while(temp!=NULL)
{
if(key==temp->data)
{
printf("search is successful");
return;
}
temp=temp->right;
}
if(temp==NULL)
printf("search is unsucsessful");
}
void main(void)
{
int ch, n;
clrscr();
while(1)
{
ch = menu();
switch(ch)
{
case 1 :printf("\n Enter Number of nodes to create: ");
scanf("%d", &n);
createlist(n);
printf("\n List created..");
break;
case 2 :dll_insert_beg();
break;
case 3 :dll_insert_end();
break;
case 4 :dll_insert_mid();
break;
case 5 :dll_delete_beg();
break;
case 6 :dll_delete_last();
break;
case 7 :dll_delete_mid();
break;
case 8:display_left_to_right();
break;
case 9:display_right_to_left();
break;
case 10:traverse_left_to_right();
break;
case 11 :traverse_right_to_left();
break;
case 12:search();
break;
case 13 :printf("\n Number of nodes: %d", countnode(start));
break;
case 14:exit(0);
}
}
getch();
}
Circular Single Linked List: It is just a single linked list in which the link field of the last node
points back to the address of the first node. A circular linked list has no beginning and no end. It is
necessary to establish a special pointer called start pointer always pointing to the first node of the list.
Circular linked lists are frequently used instead of ordinary linked list because many operations are
much easier to implement. In circular linked list no null pointers are used, hence all pointers contain
valid address.
A circular single linked list is shown in the following figure.
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;
newnode -> next = start;
• If the list is not empty, follow the steps given below:
last = start;
while(last -> next != start)
last = last -> next;
newnode -> next = start;
start = newnode;
last -> next = start;
The function cll_insert_beg(), is used for inserting a node at the beginning. Figure shows inserting a
node into the circular single linked list at the beginning.
Inserting a node at the end: The following steps are followed to insert a new node at the end of the
list:
• Get the new node using getnode().
newnode = getnode();
• If the list is empty, assign new node as start.
start = newnode;
newnode -> next = start;
• If the list is not empty follow the steps given below:
temp = start;
while(temp -> next != start)
temp = temp -> next;
temp -> next = newnode;
newnode -> next = start;
The function cll_insert_end(), is used for inserting a node at the end. The following Figure shows
inserting a node into the circular single linked list at the end.
Deleting a node at the beginning: The following steps are followed, to delete a node at the
beginning of the list:
• If the list is empty, display a message ‘Empty List’.
• If the list is not empty, follow the steps given below:
last = temp = start;
while(last -> next != start)
last = last -> next;
start = start -> next;
last -> next = start;
• After deleting the node, if the list is empty then start = NULL.
The function cll_delete_beg(), is used for deleting the first node in the list. The following Figure
shows deleting a node at the beginning of a circular single linked list.
Deleting a node at the end: The following steps are followed to delete a node at the end of the list:
• If the list is empty, display a message ‘Empty List’.
• If the list is not empty, follow the steps given below:
temp = start;
prev = start;
while(temp -> next != start)
{
prev = temp;
temp = temp -> next;
}
Traversing a circular single linked list from left to right:The following steps are followed, to
traverse a list from left to right:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
do
{
printf("%d ", temp -> data);
temp = temp -> next;
} while(temp != start);
Program: Write a c program which Implements Circular Single Linked List operations.
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
struct cslinklist
{
int data;
struct cslinklist *next;
};
typedef struct cslinklist node;
node *start = NULL;
int nodectr;
node* getnode()
{
node * newnode;
newnode = (node *) malloc(sizeof(node));
printf("\n Enter data: ");
scanf("%d", &newnode -> data);
newnode -> next = NULL;
return newnode;
}
int menu()
{
CSE DEPT. G RAJASEKHAR REDDY Page 165
C LANGUAGE
int ch;
clrscr();
printf("\n 1. Create a list ");
printf("\n\n--------------------------");
printf("\n 2. Insert a node at beginning ");
printf("\n 3. Insert a node at end");
printf("\n 4. Insert a node at middle");
printf("\n\n--------------------------");
printf("\n 5. Delete a node from beginning");
printf("\n 6. Delete a node from Last");
printf("\n 7. Delete a node from Middle");
printf("\n\n--------------------------");
printf("\n 8. Display the list");
printf("\n 9. Exit");
printf("\n\n--------------------------");
printf("\n Enter your choice: ");
scanf("%d", &ch);
return ch;
}
void createlist(int n)
{
int i;
node *newnode;
node *temp;
nodectr = n;
for(i = 0; i < n ; i++)
{
newnode = getnode();
if(start == NULL)
{
start = newnode;
}
else
{
temp = start;
while(temp -> next != NULL)
temp = temp -> next;
temp -> next = newnode;
}
}
newnode ->next = start; /* last node is pointing to starting node */
}
void display()
{
node *temp;
temp = start;
printf("\n The contents of List (Left to Right): ");
if(start == NULL )
printf("\n Empty List");
else
{
do
{
printf("\t %d ", temp -> data);
temp = temp -> next;
} while(temp != start);
printf(" X ");
}
}
void cll_insert_beg()
{
node *newnode, *last;
newnode = getnode();
if(start == NULL)
{
start = newnode;
newnode -> next = start;
}
else
{
last = start;
while(last -> next != start)
last = last -> next;
newnode -> next = start;
start = newnode;
last -> next = start;
}
printf("\n Node inserted at beginning..");
nodectr++;
}
void cll_insert_end()
{
node *newnode, *temp;
newnode = getnode();
if(start == NULL )
{
start = newnode;
newnode -> next = start;
}
else
{
temp = start;
while(temp -> next != start)
temp = temp -> next;
temp -> next = newnode;
newnode -> next = start;
}
printf("\n Node inserted at end..");
nodectr++;
}
void cll_insert_mid()
{
node *newnode, *temp, *prev;
int i, pos ;
newnode = getnode();
printf("\n Enter the position: ");
scanf("%d", &pos);
if(pos > 1 && pos < nodectr)
{
temp = start;
prev = temp;
i = 1;
while(i < pos)
{
prev = temp;
temp = temp -> next;
i++;
}
prev -> next = newnode;
newnode -> next = temp;
nodectr++;
printf("\n Node inserted at middle..");
}
else
printf("position %d of list is not a middle position ", pos);
}
void cll_delete_beg()
{
node *temp, *last;
if(start == NULL)
{
printf("\n No nodes exist..");
getch();
return ;
}
else
{
last = temp = start;
while(last -> next != start)
last = last -> next;
start = start -> next;
last -> next = start;
free(temp);
nodectr--;
printf("\n Node deleted..");
if(nodectr == 0)
start = NULL;
}
}
void cll_delete_last()
{
node *temp,*prev;
if(start == NULL)
{
printf("\n No nodes exist..");
getch();
return ;
}
else
{
temp = start;
prev = start;
while(temp -> next != start)
{
prev = temp;
temp = temp -> next;
}
prev -> next = start;
free(temp);
nodectr--;
if(nodectr == 0)
start = NULL;
printf("\n Node deleted..");
}
}
void cll_delete_mid()
{
int i = 0, pos;
node *temp, *prev;
if(start == NULL)
{
printf("\n No nodes exist..");
getch();
return ;
}
else
{
printf("\n Which node to delete: ");
scanf("%d", &pos);
if(pos > nodectr)
{
printf("\nThis node does not exist");
getch();
return;
}
if(pos > 1 && pos < nodectr)
{
temp=start;
prev = start;
i = 0;
while(i < pos - 1)
{
prev = temp;
temp = temp -> next ;
i++;
}
prev -> next = temp -> next;
free(temp);
nodectr--;
printf("\n Node Deleted..");
}
else
{
printf("\n It is not a middle position..");
getch();
}
}
}
void main(void)
{
int result;
int ch, n;
clrscr();
while(1)
{
ch = menu();
switch(ch)
{
case 1 :if(start == NULL)
{
printf("\n Enter Number of nodes to create: ");
scanf("%d", &n);
createlist(n);
printf("\nList created..");
}
else
printf("\n List is already Exist..");
break;
case 2 :cll_insert_beg();
break;
case 3 :cll_insert_end();
break;
case 4 :cll_insert_mid();
break;
case 5 :cll_delete_beg();
break;
case 6 :cll_delete_last();
break;
case 7 :cll_delete_mid();
break;
case 8 :display();
break;
case 9 :exit(0);
}
getch();
}
}
Circular Double Linked List:A circular double linked list has both successor pointer and
predecessor pointer in circular manner. The objective behind considering circular double linked list
is to simplify the insertion and deletion operations performed on double linked list. In circular double
linked list the right link of the right most node points back to the start node and left link of the first
node points to the last node.
A circular double linked list is shown in figure
start = newnode;
newnode -> left = start;
newnode -> right = start;
• If the list is not empty, follow the steps given below:
newnode -> left = start -> left;
newnode -> right = start;
start -> left -> right = newnode;
start -> left = newnode;
start = newnode;
The function cdll_insert_beg(), is used for inserting a node at the beginning. The below Figure shows
inserting a node into the circular double linked list at the beginning.
Inserting a node at the end: The following steps are followed to insert a new node at the end of the
list:
• Get the new node using getnode()
newnode=getnode();
• If the list is empty, then
start = newnode;
newnode -> left = start;
newnode -> right = start;
• If the list is not empty follow the steps given below:
newnode -> left = start -> left;
newnode -> right = start;
start -> left -> right = newnode;
start -> left = newnode;
The function cdll_insert_end(), is used for inserting a node at the end. The below Figure shows
inserting a node into the circular linked list at the end.
Inserting a node at an intermediate position: The following steps are followed, to insert a new
node in an intermediate position in the list:
• Get the new node using getnode().
newnode=getnode();
• Ensure that the specified position is in between first node and last node. If not, specified
position is invalid. This is done by countnode() function.
• Store the starting address (which is in start pointer) in temp. Then traverse the temp pointer
upto the specified position.
• After reaching the specified position, follow the steps given below:
newnode -> left = temp;
newnode -> right = temp -> right;
temp -> right -> left = newnode;
temp -> right = newnode;
nodectr++;
The function cdll_insert_mid(), is used for inserting a node in the intermediate position. The below
Figure shows inserting a node into the circular double linked list at a specified intermediate position
other than beginning and end.
Deleting a node at the beginning: The following steps are followed, to delete a node at the
beginning of the list:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
start = start -> right;
temp -> left -> right = start;
start -> left = temp -> left;
The function cdll_delete_beg(), is used for deleting the first node in the list. The below Figure shows
deleting a node at the beginning of a circular double linked list.
Deleting a node at the end: The following steps are followed to delete a node at the end of the list:
• If list is empty then display ‘Empty List’ message
• If the list is not empty, follow the steps given below:
temp = start;
while(temp -> right != start)
temp = temp -> right;
temp -> left -> right = temp -> right;
temp -> right -> left = temp -> left;
The function cdll_delete_last(), is used for deleting the last node in the list. The below Figure shows
deleting a node at the end of a circular double linked list.
Deleting a node at Intermediate position: The following steps are followed, to delete a node from
an intermediate position in the list (List must contain more than two node).
• If list is empty then display ‘Empty List’ message.
Traversing a circular double linked list from left to right: The following steps are followed, to
traverse a list from left to right:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
{
int ch;
clrscr();
printf("\n 1. Create ");
printf("\n\n--------------------------");
printf("\n 2. Insert a node at Beginning");
printf("\n 3. Insert a node at End");
printf("\n 4. Insert a node at Middle");
printf("\n\n--------------------------");
printf("\n 5. Delete a node from Beginning");
printf("\n 6. Delete a node from End");
printf("\n 7. Delete a node from Middle");
printf("\n\n--------------------------");
printf("\n 8. Display the list from Left to Right");
printf("\n 9. Display the list from Right to Left");
printf("\n 10.Exit");
printf("\n\n Enter your choice: ");
scanf("%d", &ch);
return ch;
}
void cdll_createlist(int n)
{
int i;
node *newnode, *temp;
if(start == NULL)
{
nodectr = n;
for(i = 0; i < n; i++)
{
newnode = getnode();
if(start == NULL)
{
start = newnode;
newnode -> left = start;
newnode ->right = start;
}
else
{
newnode -> left = start -> left;
newnode -> right = start;
start -> left->right = newnode;
start -> left = newnode;
}
}
}
else
printf("\n List already exists..");
}
void cdll_display_left_right()
{
node *temp;
temp = start;
if(start == NULL)
printf("\n Empty List");
else
{
printf("\n The contents of List: ");
printf(" %d ", temp -> data);
temp = temp -> right;
while(temp != start)
{
printf(" %d ", temp -> data);
temp = temp -> right;
}
}
}
void cdll_display_right_left()
{
node *temp;
temp = start;
if(start == NULL)
printf("\n Empty List");
else
{
printf("\n The contents of List: ");
do
{
temp = temp -> left;
printf("\t%d", temp -> data);
} while(temp != start);
}
}
void cdll_insert_beg()
{
node *newnode;
newnode = getnode();
nodectr++;
if(start == NULL)
{
start = newnode;
newnode -> left = start;
newnode -> right = start;
}
else
{
newnode -> left = start -> left;
newnode -> right = start;
start -> left -> right = newnode;
start -> left = newnode;
start = newnode;
}
}
void cdll_insert_end()
{
node *newnode,*temp;
newnode = getnode();
nodectr++;
if(start == NULL)
{
start = newnode;
newnode -> left = start;
newnode -> right = start;
}
else
{
newnode -> left = start -> left;
newnode -> right = start;
start -> left -> right = newnode;
start -> left = newnode;
}
printf("\n Node Inserted at End");
}
void cdll_insert_mid()
{
node *newnode, *temp, *prev;
int pos, ctr = 1;
newnode = getnode();
printf("\n Enter the position: ");
scanf("%d", &pos);
if(pos - nodectr >= 2)
{
printf("\n Position is out of range..");
return;
}
if(pos > 1 && pos <= nodectr)
{
temp = start;
while(ctr < pos - 1)
{
temp = temp -> right;
ctr++;
}
newnode -> left = temp;
newnode -> right = temp -> right;
temp -> right -> left = newnode;
temp -> right = newnode;
nodectr++;
printf("\n Node Inserted at Middle.. ");
}
else
printf("position %d of list is not a middle position", pos);
}
void cdll_delete_beg()
{
node *temp;
if(start == NULL)
{
printf("\n No nodes exist..");
getch();
return ;
}
else
{
nodectr--;
if(nodectr == 0)
{
free(start);
start = NULL;
}
else
{
temp = start;
start = start -> right;
temp -> left -> right = start;
start -> left = temp -> left;
free(temp);
}
printf("\n Node deleted at Beginning..");
}
}
void cdll_delete_last()
{
node *temp;
if(start == NULL)
{
printf("\n No nodes exist..");
getch();
return;
}
else
{
nodectr--;
if(nodectr == 0)
{
free(start);
start = NULL;
}
else
{
temp = start;
while(temp -> right != start)
temp = temp -> right;
temp -> left -> right = temp -> right;
temp -> right -> left = temp -> left;
free(temp);
}
printf("\n Node deleted from end ");
}
}
void cdll_delete_mid()
{
int ctr = 1, pos;
node *temp;
if( start == NULL)
{
printf("\n No nodes exist..");
getch();
return;
}
else
{
printf("\n Which node to delete: ");
scanf("%d", &pos);
if(pos > nodectr)
{
printf("\nThis node does not exist");
getch();
return;
}
if(pos > 1 && pos < nodectr)
{
temp = start;
while(ctr < pos)
{
temp = temp -> right ;
ctr++;
}
temp -> right -> left = temp -> left;
temp -> left -> right = temp -> right;
free(temp);
printf("\n node deleted..");
nodectr--;
}
else
{
printf("\n It is not a middle position..");
getch();
}
}
}
void main(void)
{
int ch,n;
clrscr();
while(1)
{
ch = menu();
switch( ch)
{
Example: Write a c program which implements stack operations using linked list.
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
struct stack
{
int data;
struct stack *next;
};
void push();
void pop();
void display();
typedef struct stack node;
CSE DEPT. G RAJASEKHAR REDDY Page 182
C LANGUAGE
node *start=NULL;
node *top = NULL;
node* getnode()
{
node *temp;
temp=(node *) malloc( sizeof(node)) ;
printf("\n Enter data ");
scanf("%d", &temp -> data);
temp -> next = NULL;
return temp;
}
void push(node *newnode)
{
node *temp;
if(newnode == NULL )
{
printf("\n Stack Overflow..");
return;
}
if(start ==NULL)
{
start = newnode;
top = newnode;
}
else
{
temp = start;
while( temp -> next != NULL)
temp = temp -> next;
temp -> next = newnode;
top = newnode;
}
printf("\n\n\t Data pushed into stack");
}
void pop()
{
node *temp;
if(top == NULL)
{
printf("\n\n\t Stack underflow");
return;
}
temp = start;
if( start -> next == NULL)
{
printf("\n\n\t Popped element is %d ", top -> data);
start = NULL;
free(top);
top = NULL;
}
else
{
while(temp -> next != top)
{
temp = temp -> next;
}
temp -> next = NULL;
printf("\n\n\t Popped element is %d ", top -> data);
free(top);
top = temp;
}
}
void display()
{
node *temp;
if(top == NULL)
printf("\n\n\t\t Stack is empty ");
else
{
temp = start;
printf("\n\n\n\t\t Elements in the stack: \n");
printf("%5d ", temp -> data);
while(temp != top)
{
temp = temp -> next;
printf("%5d ", temp -> data);
}
}
}
char menu()
{
char ch;
clrscr();
printf("\n \tStack operations using pointers.. ");
printf("\n -----------**********-------------\n");
printf("\n 1. Push ");
printf("\n 2. Pop ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
ch = getche();
return ch;
}
void main()
{
char ch;
node *newnode;
do
{
ch = menu();
switch(ch)
{
case '1' : newnode = getnode();
push(newnode);
break;
case '2' :pop();
break;
case '3' :display();
break;
case '4':return;
}
} while( ch != '4' );
getch();
}
Linked List Implementation of Queue:We can represent a queue as a linked list. In a queue data is deleted
from the front end and inserted at the rear end. We can perform similar operations on the two ends of a list.
We use two pointers front and rear for our linked queue implementation.The linked queue looks as shown in
figure
Example: Write a c program which implements queue operations using linked list.
# include <stdlib.h>
# include <conio.h>
struct queue
{
int data;
struct queue *next;
};
typedef struct queue node;
node *front = NULL;
node *rear = NULL;
node* getnode()
{
node *temp;
temp = (node *) malloc(sizeof(node)) ;
printf("\n Enter data ");
temp = front;
printf("\n\n\n\t\t Elements in the Queue are: ");
while(temp != NULL )
{
printf("%5d ", temp -> data);
temp = temp -> next;
}
}
}
char menu()
{
char ch;
clrscr();
printf("\n \t..Queue operations using pointers.. ");
printf("\n\t -----------**********-------------\n");
printf("\n 1. Insert ");
printf("\n 2. Delete ");
printf("\n 3. Display");
printf("\n 4. Quit ");
printf("\n Enter your choice: ");
ch = getche();
return ch;
}
void main()
{
char ch;
do
{
ch = menu();
switch(ch)
{
case '1' : insertQ();
break;
case '2' : deleteQ();
break;
case '3' : displayQ();
break;
case '4':return;
}
} while(ch != '4');
getch();
}
UNIT-VI
SEARCHING AND SORTING TECHNIQUES
Searching: Searching is the process of finding the location of a target element among a list of elements.
Or
Process of finding a particular element in a collection of elements is called searching.
Algorithm:
Step 1: If key==a[i] then return position of key element i.e element found
Repeat step1 until end of the list.
Step 2: else return -1 i.e element not found
Example: Consider the list of elements as shown below
0 1 2 3 4 5 6 7 8
4 10 5 15 6 30 40 9 7
Suppose we want to search for an element 15, i.e. key=15
key(15) is compared with 1st element(i.e. 0th location) that is 15==4,false, then proceed to next step
key(15) is compared with 2st element(i.e. 1st location) that is 15==10,false, then proceed to next step
key(15) is compared with 3rd element(i.e. 2nd location) that is 15==5,false, then proceed to next step
key(15) is compared with 4th element(i.e. 3rd location) that is 15==15,true, element is found at 3rd
location
Example: Write a C program to search the element in the list using linear search.
#include<stdio.h>
#include<conio.h>
void main
{
int a[20],i,key,n,pos;
printf(“enter the no. of elements”);
scanf(“%d”,&n);
printf(“enter the elements into array”);
for(i=0;i<n;i++)
scanf(“%d”,&a[i]);
printf(“enter the element to be searched:\n”);
scanf(“%d”,&key);
for(i=0;i<n;i++)
{
if(key==a[i])
{
printf(“\n Element found at position %d“,i+1);
exit(0);
}
}
printf(“\n unsuccessfull search”);
}
Example: Write a C program to search the element in the list using linear search.
#include<stdio.h>
#include<conio.h>
#define MAXSIZE 100
int linearsearch(int a[],int n,int key);
int a[MAXSIZE],n,key;
void main
{
int i,pos;
printf(“enter the no. of elements”);
scanf(“%d”,&n);
printf(“enter the elements into array”);
for(i=0;i<n;i++)
scanf(“%d”,&a[i]);
printf(“enter the element to be searched:\n”);
scanf(“%d”,&key);
pos=-1;
pos=linearsearch(a,n,key);
if(pos!=-1)
printf(“\n search successful, element found at position %d“,pos);
else
printf(“\n unsuccessfull search”);
}
int linearsearch(int a[],int n,int key)
{
int i;
for(i=0;i<n;i++)
{
if(key==a[i])
return i;
}
return -1;
}
Example: A Recursive program for linear search:
# include <stdio.h>
# include <conio.h>
void linear_search(int a[], int key, int position, int n)
{
if(position<n)
{
if(a[position] == key)
printf("\n Data Found at %d ", position+1);
else
linear_search(a, key, position + 1, n);
}
else
printf("\n Data not found");
}
void main()
{
Disadvantages:
This method is inefficient when large number of elements are placed in list because time taken for
search is more
Binary search: Binary search is another simple searching method. To implement binary search
method, the elements must be in sorted order. So you can apply any one of the sorting technique
before using the binary search (for example bubble sort).this method uses divide and conquer
strategy.
Procedure:
Assume we are searching for key in a list that contains elements in ascending order(or descending
order)
the list is divided into two parts.
The key is compared with element in the middle position of list. If the key matches with the middle
element, then search will end and return position of key.
If the key is less than mid positioned element, then the element to be found must be in the first half
of list.
If the key is greater than mid positioned element, then the element to be found must be in the
second half of list.
Repeat the procedure till no more partitions are available.
Return -1 if element is not found.
Algorithm:
Step1: Initialization f=0 and l=n-1
Step2: Repeat step 3 to step 4 while upper bound (l) is >= lower bound(f).
Step3: Obtain the index of middle value i.e; mid=(f+l)/2
Step4: If key < a[mid] then l = mid-1
Otherwise if key >a[mid]then f = mid+1
Otherwise return (mid) i.e. “element found”
Step5: Return -1 i.e. “element not found”
Example:
2 12 30 35 46 53 60 70 75 Consider a list of
sorted elements stored
in an array A,
f=0 l=8
Let the key to be searched = 30
The number of elements in the list is N= 9
mid = [ ( f+l ) / 2 ] i.e., [ ( 0+8 ) / 2 ] = 4
2 12 30 35 46 53 60 70 75
f=0 mid=4 l =8
Key < a[mid] i.e; 30 < 46 is true so search first half of the array
l=mid–1 i.e l=4-1=3
2 12 30 35 46 53 60 70 75
f=0 l= 3
mid = [ ( f+l ) / 2 ] i.e., 0+3/2 = 1.5
2 12 30 35 46 53 60 70 75
f=0 mid=1 l=3
Key>mid i.e; 30> 12 is true So second half of list is searched.
f= mid + 1 i.e., f=1+1=2
2 12 30 35 46 53 60 70 75
f=2 l=3
Mid = 2+3/2=2.5
2 12 30 35 46 53 60 70 75
f= mid=2 l=3
}
Example: Write a C program that searches a value in a stored array using binary search.
#include<stdio.h>
#include<conio.h>
#define MAXSIZE 500
int binsearch(int elements[],int maxsize,int key);
void bubblesort(int elements[],int maxsize);
int elements[MAZSIZE],maxsize,key;
void main()
{
int i,pos;
printf(“enter the no. of elements”);
scanf(“%d”,&maxsize);
printf(“enter the elements into array”);
for(i=0;i<n;i++)
scanf(“%d”,&elements[i]);
printf(“enter the element to be searched:\n”);
scanf(“%d”,&key);
bubblesort(elements,maxsize);
pos=-1;
pos=binsearch(elements,maxsize,key);
if(pos!=-1)
printf(“\n search successful, element found at position %d“,pos+1);
else
printf(“\n unsuccessfull search”);
}
void bubblesort(int elements[],int maxsize)
{
int i,j,temp;
for(i=0;i<maxsize-1;i++)
{
for(j=i;j<maxsize;j++)
{
if(elements[i]>elements[j])
{
temp=elements[i];
elements[i]=elements[j];
elements[j]=temp;
}
}
}
}
int linearsearch(int elements[],int maxsize,int key)
{
int i,first,middle,last;
first=0;
last=maxsize-1;
while(last>=first)
{
middle=(first+last)/2;
if(key>elements[middle])
first=middle+1;
else if(key<elements[middle])
last=middle-1;
else
return middle;
}
return -1;
}
Example: Write a c program which implements binary search technique using recursion.
#include<stdio.h>
#include<conio.h>
#define MAXSIZE 500
int binsearch(int elements[],int maxsize,int key,int first,int last);
void bubblesort(int elements[],int maxsize);
int elements[MAZSIZE],maxsize,key;
void main()
{
int i,pos;
printf(“enter the no. of elements”);
scanf(“%d”,&maxsize);
printf(“enter the elements into array”);
for(i=0;i<n;i++)
scanf(“%d”,&elements[i]);
printf(“enter the element to be searched:\n”);
scanf(“%d”,&key);
bubblesort(elements,maxsize);
pos=-1;
pos=binsearch(elements,maxsize,key,0,maxsize-1);
if(pos!=-1)
printf(“\n search successful, element found at position %d“,pos+1);
else
printf(“\n unsuccessfull search”);
}
void bubblesort(int elements[],int maxsize)
{
int i,j,temp;
for(i=0;i<maxsize-1;i++)
{
for(j=i;j<maxsize;j++)
{
if(elements[i]>elements[j])
{
temp=elements[i];
elements[i]=elements[j];
elements[j]=temp;
}
}
}
}
int binsearch(int elements[],int maxsize,int key,int first,int last)
{
int i,middle;
middle=-1;
if(first<=last)
{
middle=(first+last)/2;
if(key>elements[middle])
middle=binsearch(elements,maxsize,key,middle+1,last);
else if(key<elements[middle])
middle=binsearch(elements,maxsize,key,first,middle-1);
}
return middle;
}
Sorting: The process of arranging the elements in a list in ascending or descending order is called sorting.
Sorting will make searching an easy process. For example, we want to obtain the telephone number of a
person. If the telephone directory is not arranged in alphabetical order, one has to search from the very first
page to till the last page. If the directory is sorted, we can easily search for the telephone number.
Some of the sorting techniques are
bubble sort
Insertion
quick sort
Selection sort
Merge sort
Bubble Sort: This is the simplest and oldest sorting technique when compared with all the other sorting
techniques. It is also called as exchange sort. In this sorting technique the adjacent elements are compared
and interchanged if necessary.
Process:
7.Compare first and second elements. If the first element is greater than the second element ,
then interchange these two elements.
Compare second and third elements. If the second element is greater than third element then make
an interchange.
The process is repeated till the last and second last element is compared and swapped if necessary.
This completes the first pass. At the end of the first pass, the largest element will get its exact final
position i.e it occupies the last position.
The steps1 to step3 are repeated n-1 times for the elements between 1 to n-1 because the nth
element is already sorted.
After completion of n-1 passes, the list is in sorted order.
Algorithm: Bubblesort(A,N)
Step 1: repeat step 2 for i=0 to n-1
Step 2: repeat for j=0 to n-i-1
Step 3: If A[j]>A[j+1]
Swap A[j] and A[j+1]
[End of inner loop]
[End of outer loop]
Step 4: Exit
Example: Consider the unsorted elements 75 18 90 5 25
pass1: 75 18 90 5 25 75<18 is false, so interchange 75 and 18
18 75 90 5 25 75<90 is true
18 75 90 5 25 90<5 is false, so interchange 90 and 5
18 75 5 90 25 90<25 is false, so interchange 90 and 25
18 75 5 25 90
After completion of the 1 st iteration the first maximum element i.e..,90 is placed in a correct
position.
pass2: 18 75 5 25 90 18<75 is true
18 75 5 25 90 75<5 is false, so interchange 75 and 5
18 5 75 25 90 75<25 is false, so interchange 75 and 25
18 5 25 75 90
After completion of the 2nd iteration the second maximum value i.e., 75 is placed in a correct
position.
pass3: 18 5 25 75 90 18<5 is false, so interchange 18 and 5
5 18 25 75 90 18<25 is true
5 18 25 75 90
After completion of the 3rd iteration the second maximum value i.e., 25 is placed in a correct
position.
pass4: 5 18 25 75 90 5<18 is true
5 18 25 75 90
After completion of the 4th iteration the second maximum value i.e., 18 is placed in a correct
position.
Sorted list (after n-1 passes) : 5 18 25 75 90
Note: Bubble sort technique has n-1 passes where n is the number of elements.
10 20 25 35 40 45
After completion of the 5th iteration the fifth maximum element i.e., 20 placed on a correct position.
After each iteration, the larger values sink to the bottom of the array and hence it is called sinking
sort.
At the end of each iteration smaller values gradually “bubble” their way forward to the beginning of
the array and hence it is called bubble sort.
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
printf(“the sorted elements are:”);
for(i=0; i<n; i++)
printf(“%d”, a[i]);
}
Example: Write a C program to sort elements of an array using bubble sort.
#include<stdio.h>
#include<conio.h>
void bubblesort(int a[],int);
void main()
{
int i,n,temp,j,a[20];
printf("Enter the number of elements in the Array: ");
scanf("%d",&n);
printf("\nEnter the elements:\n\n");
for(i=0 ; i<n ; i++)
{
printf(" Array[%d] = ",i);
scanf("%d",&a[i]);
}
printf(“\nBefore sorting unsorted list is:\n\n”);
for(i=0 ; i<n ; i++)
printf(" %4d",arr[i]);
bubblesort(a,n);
printf("\nThe Sorted Array is:\n\n");
for(i=0 ; i<n ; i++)
printf(" %4d",arr[i]);
}
void bubblesort(int a[], int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
Example: Write a C program to perform bubble sort using recursion.
#include <stdio.h>
#include <stdlib.h>
void bubbleSort(int *data, int n)
{
int i,temp;
if (n>0)
{
for (i=1;i<n;i++)
{
if (data[i-1]>data[i])
{
temp=data[i];
data[i]=data[i-1];
data[i-1]=temp;
}
}
bubbleSort(data, n-1);
}
}
main()
{
int i, n, *data;
printf("Enter the number of inputs:");
scanf("%d", &n);
data = (int*)malloc(sizeof(int)*n);
for (i=0; i<n;i++)
scanf("%d",&data[i]);
bubbleSort(data,n);
printf("Data After Bubble Sort:\n");
for (i=0;i<n;i++)
printf("%d",data[i]);
}
Advantages:
It is relatively easy to write and understand..
Straight forward approach.
Works well for smallest list of elements.
Performance is good for nearly sorted list.
Disadvantages:
It runs slowly and hence it is not efficient, because Even if the elements are sorted, n-1
iterations are required to sort.
It is not used for sorting the list of larger size.
It is insufficient algorithm because the number of iterations increases with increase in number of
elements to be sorted
Selection sort: Selection sort is also known as push-down sorting. As the name suggests the first element of
the list is selected. It is compared with all the elements. If any element is found to be lesser than the
selected element, these two are interchanged. This procedure is repeated till all the elements in the list are
sorted.
Process:
From the list select the smallest element and interchange with the first location (0th location)
element. Now the first element is sorted.
Select the next smallest element and interchange with the second location (1st location) element.
Now the second element is sorted.
Repeat the same process till all elements in the list are sorted (The entire list gets sorted within (n-
1)th pass).
Algorithm: selectionsort(A,N)
Step 1: repeat step 2 to 5 for i=0 to N-1
Step 2: set min=i
Step 3: set j=i
Step 4: repeat for j=i+1 to N
if A[min] > A[j]
set min=j
[End inner loop]
Step 5: swap A[i] and A[min]
[End for loop]
Step 6: Exit
Example: Consider the list of unsorted elements are: 23 78 45 8 32 56
1st iteration: 23 78 45 8 32 56
8 78 45 23 32 56
nd
2 iteration: 8 78 45 23 32 56
8 23 45 78 32 56
rd
3 iteration: 8 23 45 78 32 56
8 23 32 78 45 56
th
4 iteration: 8 23 32 78 45 56
8 23 32 45 78 56
th
5 iteration: 8 23 32 45 78 56
8 23 32 45 56 78
A list of sorted elements now: 8 23 32 45 56 78
10 20 25 35 45 40
5th iteration: 10 20 25 35 45 40
10 20 25 35 40 45
#include <stdio.h>
void selectionsort(int[],int);
int main()
{
int a[10],i,n;
printf("enter the size of array:\n");
scanf("%d",&n);
printf("enter the elements of array:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("\nThe unsorted elements are:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
selectionsort(a,n);
printf("\nThe sorted elements are:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
}
void selectionsort(int a[],int n)
{
int min,temp,i,j;
for(i=0;i<n-1;i++)
{
min=i;
for(j=i+1;j<n;j++)
{
if(a[j]<a[min])
min=j;
}
temp=a[i];
a[i]=a[min];
a[min]=temp;
}
}
Example: Write a c program which implements selection sort technique using Recursion.
#include <stdio.h>
#include<conio.h>
int x[6]={77, 33, 44, 11, 66};
selectionSort(int);
main()
{
int i,n=0;
clrscr();
printf ("Array Elements before sorting: ");
for (i=0; i<5; i++)
printf ("%d ", x[i]);
selectionSort(n);
printf ("\n Array Elements after sorting: ");
for (i=0; i<5; i++)
printf ("%d ", x[i]);
}
selectionSort( int n)
{
int k, p, temp, min;
if (n==4)
return -1;
min=x[n];
p=n;
for (k=n+1;k<5;k++)
{
if (x[k]<min)
{
min=x[k];
p=k;
}
}
temp=x[n];
x[n]=x[p];
x[p]=temp;
n++;
selectionSort(n);
}
Quick sort: This sorting is also called as partition exchange sorting. This method is based on divide and
conquer technique. That is the entire list is divided into various partitions and sorting is applied again and
again on the partitions.
In this method, the list is divided into two parts, based on an element called pivot element. Usually,
the first element is considered to be the pivot element. Now move the pivot element into its correct
position in the list. The elements to the left of the pivot are less than the pivot and the elements to the
right of the pivot are greater than the pivot. The procedure of choosing a pivot and partitioning the
list is applied recursively until we get sub-lists consisting of only one element. This process proceeds
till we get the sorted list of elements.
Example: consider the following unsorted elemetns.
74 39 35 32 97 84 ==> 74 is the pivot element
Step1: 39 35 32 74 97 84 ==> 39,97 are pivot elements
step2: 35 32 39 74 84 97 ==>35,84 are pivot elements
step3: 32 35 39 74 84 97 ==>32 is pivot element
32 35 39 74 84 97
#include<stdio.h>
#define MAXSIZE 500
void quicksort(int elements[ ],int maxsize);
void sort(int elements[],int left,int right);
int elements[MAXSIZE];
void main( )
{
int I,maxsize;
printf("\nHow many elements you want to sort ? ");
scanf("%d",&maxsize);
printf("\Enter elements for an array:");
for(i=0; i<maxsize; i++)
scanf("%d",&elements[i]);
printf(“array before sorting”);
for(i=0; i<maxsize; i++)
printf(“%d”,elements[i]);
quicksort(elements,maxsize);
printf("\After Sorting the elements are:");
for(i=0;i<maxsize;i++)
printf("%3d ",elements[i]);
}
void quicksort(int elements[ ],int maxsize)
{
sort(elements,0,maxsize-1);
}
void sort(int elements[],int left,int right)
{
int pivot,l,r;
l=left;
r=right;
pivot=elements[left];
while(left<right)
{
while((elements[right]>=pivot)&&(left<right))
right--;
if(left!=right)
{
elements[left]=elements[right];
left++;
}
while((elements[left]<=pivot)&&(left<right))
left++;
if(left!=right)
{
elements[right]=elements[left];
right--;
}
}
elements[left]=pivot;
pivot=left;
left=l;
right=r;
if(left<pivot)
sort(elements,left,pivot-1);
if(right>pivot)
sort(elements,pivot+1,right);
}
Advantages:
This is faster sorting method among all.
Its efficiency is also relatively good.
It requires relatively small amount of memory.
Disadvantages:
It is a complex method of sorting so, it is little hard to implement than the other sorting
methods.
Insertion Sort: The insertion sort procedure is similar to the way we play cards. After shuffling the cards, we
pick each card and insert it into the proper place by shift the remaining cards. This process is repeated until
all the cards in the hand are in the correct sequence. So that cards in hand are arranged in ascending order.
Process:
Select the second element in the list and compare it with the first element. If the first element is
greater than the second element then the second element is inserted at first location by shifting the
first element to the second position. Otherwise proceed with the next step.
Select the third element in the list and compare it with the two sorted elements and insert at the
appropriate position.
Select the fourth element and compare it with previous three sorted elements and insert it in proper
position among the elements which are compared.
Repeat the process until we get sorted list. The entire list gets sorted within (n-1)th pass.
Algorithm: insertionsort(A,N)
#include <stdio.h>
CSE DEPT. G RAJASEKHAR REDDY Page 205
C LANGUAGE
void insertionsort(int[],int);
int main()
{
int a[10],i,n;
printf("enter the size of array:\n");
scanf("%d",&n);
printf("enter the elements of array:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("\nThe unsorted elements are:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
insertionsort(a,n);
printf("\nThe sorted elements are:\n");
for(i=0;i<n;i++)
printf("%3d",a[i]);
}
void insertionsort(int a[],int n)
{
int i,j,index;
for(i=1;i<n;i++)
{
index=a[i];
j=i;
while((j>0)&&(a[j-1]>index))
{
a[j]=a[j-1];
j--;
}
a[j]=index;
}
}
Advantages:
It is easy to implement and efficient to use on small sets of data.
It can be efficiently implemented on data sets that are already substantially sorted.
It requires less memory space.
Disadvantages:
It is less efficient on list containing more number of elements.
Merge sort: This sorting method uses divide and conquer method. The basic concept of merge sort is to
divide the list into two smaller sub-lists of approximately equal size. And continue splitting until each sub list
contains only one element. After this, merge the two parts containing one element into one sorted list and
Continue merging parts until finally there is only one sorted list.
Process:
Consider the initial list and divide the list into two sub-lists. Again these sub-lists are divided into
many numbers of sub-lists until each and every sub-list contains single element.
Combine these sub-lists into sorted order. Finally we will get list of elements in sorted order.
Algorithm: Merge(A,LOW,MID,HIGH)
Step 1: Initialize i=LOW,j=MID+1,k=0
Step 2: repeat while (i<=MID) and (j<=HIGH)
If A[i]<A[j]
Set temp[k++]=A[i++]
Else
Set temp[k++]=A[j++]
[End of If]
[End of for]
Step 3: Repeat while j<=HIGH
Set temp[k++]=A[i++]
[End of loop]
Repeat while i<=MID
Set temp[k++]=A[i++]
[End of loop]
Step 4: [copy the contents of temp back to A]
Repeat for k=LOW to HIGH
Set A[k]=temp[k]
[End of loop]
Step 5: Exit
Mergesort(A,LOW,HIGH)
Step 1: if LOW<HIGH
Set MID=(LOW+HIGH)/2
Call Mergesort(A,LOW,MID)
Call Mergesort(A,MID+1,HIGH)
Call Merge(A,LOW,MID,HIGH)
[End of If]
Step 2:Exit
Example: A list of unsorted elements are: 39 9 81 45 90 27 72 18
#include<stdio.h>
void mergesort(int a[],int,int);
void merge(int a[],int,int,int);
main()
{
int a[10],i,n;
printf("enter n");
scanf("%d",&n);
printf("enter");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("the unsorted list is:\n\n");
for(i=0;i<n;i++)
printf("%5d",a[i]);
mergesort(a,0,n-1);
printf("The final sorted list is:\n\n\n");
for(i=0;i<n;i++)
printf("%5d",a[i]);
}
void mergesort(int a[],int low,int high)
{
int mid;
if(low<high)
{
mid=(low+high)/2;
mergesort(a,low,mid);
mergesort(a,mid+1,high);
merge(a,low,mid,high);
}
}