DATA STRUCTURES IN C
MADE SIMPLE
( Second Edition)
KANNAN BALAKRISHNAN
SUMI HARIDAS
UMESH RAM
2011
Preface
For many years the authors have felt the need of a simple book in data structures. This book is written especially for students in undergraduate classes.
We have included basic concepts like stacks ,queues, linked lists, graphs, trees, searching and sorting algorithms in this book.Even though we do not claim any in depth treatment of the subject in this book, we hope that it will be surely useful for students who are studying data structures in C for the first time.
Many programs are included in the book. Also a companion blog i s available at http://dssimple.wordpress.com .
We hope that this book will be of great use to students. Cochin
TABLE OF CONTENTS Chapte r 1 Pointers 1.1 What Is A Pointer? 1.2 Pointer Declaration 1.3 Pointer Arithmetic
1.4 Accessing Variables Using Pointer 1.5 Address Operator (&)
1.6 Dereferencing Operator (*)
1.7 .One And Two Dimensional Arrays Using Pointers 1.8 Void Pointers
1.9 Pointers In Function Arguments 1.10 Recursion 1.11 Direct Recursion 1.12 Indirect Recursion 1.13 Array Of Pointers 1.14 Pointer To Pointer 1.15 Pointers To Strings 1.16 Pointers to functions Exercises Chapter 2
Structures and Unions 2.1 Definition
2.2 Accessing The Members Of A Structure 2.3 Array Of Structures
2.4 Structures Within Structure (Nested Structure) 2.5 Pointers To Structures
2.6 Structure In Functions 2.7 Unions
2.8 Difference and Similarity Between Structure And Union Exercises
Chapter 3
Strings and String Operations 3.1 Strings 3.2 Strlen() 3.3 Strcmp() 3.4 Strcat() 3.5 Strcpy() 3.6 Pattern Matching
3.7 Dynamic Memory Allocation 3.8 Malloc()
3.10 Realloc
3.11 Freeing Memory Exercises
Chapter 4
Sorting and Searching 4.1 Sorting
4.2 Different Sorting Techniques 4.3 Bubble sort Implementation 4.4 Selection sort
4.5 Selection sort implementation 4.6 Insertion sort
4,7 Insertion sort Implementation 4.8 Quick sort
4.9 Quick sort implementation 4.10 Merge Sort
4.11 Merge Sort Example 4.12 Bucket Sort
4.13 Heap Sort
4.14 Comparison Of Different Sorting Algorithms 4.15 Searching
4.16 Linear Search 4.17 Binary Search
4.18 Difference between Linear Search & Binary Search Exercises
5
Chapter 5 Stacks and Queues 5.1 Stack
5.2 Implementation of Stack using Arrays and pointers 5.3 Applications of Stacks
5.4 Queues
5.5 Circular Queue 5.6 Priority Queue 5.7 Dequeue
5.8 Input Restricted Dequeues 5.9 Output Restricted Dequeues 5.10 Applications of Queues Exercises
Chapter 6 Linked lists 6.1 Linked List
6.2 Creation of Linked List 6.3 Inserting Node
6.4 Deletion of Nodes 6.5 Doubly Linked List
6.6 Operations on Doubly Linked List 6.7 Circular Linked List
6.8 Circular Doubly Linked List
6.9 Advantages/Disadvantages of Linked List Exercises Chapter 7 Trees 7.1 Tree 7.2 Root 7.3 Degree 7.4 Path length 7.5 Level 7.6 Forest 7.7 Labeled Trees 7.8 Binary Tree 7.9 Application Of Trees 7.10 Binary Tree Operations 7.11 Tree Traversal Methods 7.12 The Binary Search Tree 7.13 Threaded Binary Tree
7.14 Use Of Threaded Binary Tree Exercises
Chapter 8 Graphs 8.1 Graphs
8.2 Definition
8.3 Adjacency List Representation 8.4 DFS And BFS
8.5 Depth First Search (DFS) 8.6 Breadth First Search (BFS) 8.7 Shortest Path
8.8 Weighted Graph 8.9 Dijkstra Algorithm Exercises
Chapter I
Pointers in ‘C’
1.1. What is a pointer?
A pointer is a data type in C, which helps the programmer to access the memory locations of variables directly. A pointer contains a memory address which is the address of a variable. So, we define a pointer as follows
Definition:
A pointer is a variable that contains the address of another variable.
We can have a pointer to any variable type. Using pointers complex data types can be declared and accessed efficiently.
1.2 Pointer Declaration:
The syntax of declaring a pointer is type *pointerName.
The type in the above declaration is called the base type of the pointer. Example:
char *x declares x as a pointer to a character variable and int *y says that y is a pointer to an integer variable.
When p is a pointer to a variable of integer type, we say that the base type of p is integer. Similarly when q is a pointer to a float variable, we say that the base type of q is float and so on.
After declaring a pointer variable one must assign values to it. That is the pointer must be assigned to some address. We can assign value to pointer in same way as any other variable data type.
int *p,*p1; P=&m;
Here the memory address of variable m is assigned to a pointer variable p. We are getting the address location of the variable, not the content of the pointer variable.
• • Sum =*p1; •
Here the content of the pointer variable p1 is assigned to the variable sum. That is, value of p1 is the address of the integer variable sum.
Figure 1.1 A pointer to p1 to an integer variable sum
Program to display the address and contents of a pointer is given next. Program1.1 #include<stdio.h> void main() { int x;
int *p; // Here A pointer variable of base type integer is declared x=50;
p=&x; //The pointer variable p is assigned the address of x printf(“Value of x is %d\n”,x);
printf(“Value of the variable pointed by p is %d\n”,*p); printf(“Address of x is %d”,p);
getch(); }
Output of the program Value of x is 50
Value of the variable pointed by p is 50 Address of x is 43522 1.2. Pointer Arithmetic
C language supports four arithmetic operations on pointers.
• Addition + • Subtraction -• Incrementation ++ • Decrementation
-Here ++ increments the pointer to the address of the next memory location of the same type variable. The increment is done not by one but by the number of bytes required for the data type. That is if an integer is 4 bytes, ++ will increment an integer pointer by 4 and not by 1. Similarly for other operators.
Also subtraction of a pointer p2 from a pointer p1 is defined only if p1 and p2 are pointers of the same base type.
Program illustrating pointer operations Program1.2 #include <stdio.h> void main() { int v,w ,*p,*q; v=80; w=90; p=&v; q=&w;
printf("Value of p before increment operation=%u \n",p); p++;
printf("Value of p after increment operation=%u\n",p); p--;
printf("Value of p after decrement operation=%u\n",p); printf("Value of q=%u\n",q);
printf("Value of p-q=%u\n",p-q); }
Output of the program
Value of p before increment operation=4276350260 Value of p after increment operation=4276350264 Value of p after decrement operation=4276350260 Value of q=4276350256
Value of p-q=1
1.3. Accessing Variables Using Pointer
In C you can see two type of unary operators for declaring a pointer type variable. They are listed below,
• Address operator & • Dereferencing operator *
1.4. Address Operator(&)
Address operator can be represented by the combination of &(ampersand) with a pointer variable .Ampersand is a unary operator that returns memory address to its operand.
The pointer operator & returns the address of the variable following it. So we can say that ‘p’ is assigned the address of x.
1.5. Dereferencing Operator(*)
This can be represented the combination of *(asterisk) along with the variable. Asterisk should be before the variable name. It is also a unary operator that returns the value of the variable located at the address.
For example: a=*p;
Here a gets the value pointed by the pointer p.
1.5.1.1.1.1. One and Two Dimensional Arrays Using Pointers
Pointers and arrays are equivalent in the following sense.
The name of the array acts as a pointer to the first element of the array. Let us explain this with two examples:
int a [50];
The above statement declares an array of integers of size 50, having elements a[0], a[1] ,.., a[49]. This is a one dimensional array.
The variable a can be used as a pointer to the array. Variable a will point to the starting address of the array, that is a [0]. The elements of this array are
a [0], a[1], …, a[49]. They are integer variables. Logically, these elements are stored in 50 consecutive memory locations. Therefore a pointer variable of base type integer can point to these elements.
We know that int *ip declares ip as an integer type pointer. Now the two statements below, taken together are equivalent to the statement a[3] = 7
ip = &a[3]; *ip = 7;
taken together are equivalent to the statement a[3] = 7
Also the statement ip = a is equivalent to saying that ip = &a[0]. Similarly, ip = a+5 is equivalent to saying that ip = &a[5].Generalizing ,We can say that the following is true.
pointer of that base type whose value is the address of a[0] and a+k points to a[k] for any k between 1 and n-1.
A two dimensional array can be represented by a matrix.The next figure shows a two-dimensional array
Figure 1.2 A two dimensional array b[3][4] with three rows and four columns.
The following statement declares a two-dimensional array. float b[3] [4].
C treats a two dimensional array as a one dimensional array of rows. Each row itself is again a one dimensional array.
Now b will point to b[0],which is the first row of the array. Also b+1, b+2, ….. Will be used to access to successive rows of the array b[ ][ ].Now b[0], is the first row .Since the first row is a one dimensional array,b[0] is a pointer to the first element b[0][0] of that array . Similarly b[1] is a pointer to the first element b[1][0] in the second row and so on. Also b[0]+j is a pointer to b[0][j]. Again
*(b+i) is actually same as b[ i ] and *(*(b+i)+j) is the pointer representation of b[i][j].
Program to display the content of a one dimensional array using pointers: Program1.3
#include<stdio.h> main() { int a[4]={1,2,3,4}; int *p1; int i,s,t1; s=4;
printf("Display the contents of array\n"); for(i=0;i<=s-1;i++) { t1= *(a+i) ; printf("value is =%d\n",t1); } }
Output of the program Display the contents of array value is =1
value is =2 value is =3 value is =4
Program to show contents of two dimensional array using pointers
Program1.4
#define maxsize 50
#include<stdio.h> void main() {
int b[maxsize][maxsize],n_of_rows, n_of_cols, i,*p, j, tvalue; printf("Enter The number of rows: ");
scanf("%d",&n_of_rows); printf("Enter the number of columns: "); scanf("%d",&n_of_cols);
for(i=0;i<=n_of_rows-1;i++) {
for(j=0;j<=n_of_cols-1;j++) {
printf("Enter the (%d,%d) element ", i,j); scanf("%d",&b[i][j]);
} } printf("Contents of array\n"); for(i=0;i<=n_of_rows-1;i++) { for(j=0;j<=n_of_cols-1;j++) { tvalue=*(*(b+i)+j); printf("%d\t",tvalue); } printf("\n"); } }
Output of the program
Enter The number of rows: 3 Enter the number of columns: 4 Enter the (0,0) element 1
Enter the (0,1) element 2 Enter the (0,2) element 3 Enter the (0,3) element 4 Enter the (1,0) element 5 Enter the (1,1) element 6 Enter the (1,2) element 7 Enter the (1,3) element 8 Enter the (2,0) element 9 Enter the (2,1) element 10 Enter the (2,2) element 11 Enter the (2,3) element 12 Contents of array 1 2 3 4 5 6 7 8 9 10 11 12 1.7 Void Pointers
Pointers to different data types are considered different. There is no implicit conversion from one type of pointer to the other.
In order to overcome this inconvenience, we use a pointer to point to multiple data types. If we don’t know what kind of value a pointer will point to then we can declare a “void pointer”.
Void pointers are commonly used in the parameter list of built–in function, such as memcpy and memset.
Void pointer can point to any data type and any other pointer can be assigned to it. But it is not considered good practice to use a void pointer unless it is required in very special cases.
1.9 Pointers in Function arguments
In function declaration you can use pointers frequently. Using pointers as arguments, we can easily rewrite a complex function. Pointer arguments enable a function to access and change variables that are passed to it.
Program illustrating the use of pointers in functions. Program1.5 #include<stdio.h> void main() { int value1,value2; value1=100; value2=200; clrscr();
printf(“values before swap()operation is %d%d\n\n”, value1, value2); swap(&value1,& value2); //Calls function
printf(“values after swap()operation is %d %d\t\n\n”, value1, value2); getch();
return(0); }
void swap(int *value1,int *value2) { int tempvalue; tempvalue=* value1; *value1=*value2; *value2=tempvalue; }
Output of the program
values before swap() operation is100 200 values after swap() operation is 200 100
Definition:
Recursion is a technique widely used to make write complex functions in a simple way. A function which invokes itself directly or indirectly is called as recursive function.
n! = 1 * 2 * , . .*n
We can use this definition to write int factorial1 (int n)
{ int i; int s; s = 1; for (i = 1; i <= n; i++) { s = s * i; } return s; }
Using recursion we can rewrite the above function. We know that n!=(n-1)!*n for n >0 . So we can rewrite the above function using follows:
int factorial2 (int n) {
If (n<=1) return 1;
return n * factorial2 (n - 1)); }
This function is an example of implementing recursion in C.
Comparing the two problems, the second version is much simpler than first.
There are two types of recursion: 1. Direct Recursion
2. Indirect Recursion
1.11 Direct Recursion
A directly recursive function is a function which contains a direct call to itself. For example, consider the function:
int f1 (int n) { if (n <= 0) return n; return (n+ f1(n- 1)); }
The above function contains a call to itself, and so it’s directly recursive. 1.12 Indirect Recursion
A function f1 is indirectly recursive if it contains a call to another function which in turn calls f1 .
The following functions are indirectly recursive. int f1(int n) { if (n<= 0) return n; return (n+ f2(n)); } int f2(int m) { return f1(m - 1); }
Here function f1 calls another function f2, which in turn calls the first function f1. So we say that this function is indirectly recursive.
1.13 Array of Pointers
When you have a large array of data items, names for example, and you want to access them in sorted order one method is to use an array of pointers. We can use array of pointers like any other array. The declaration for an integer pointer array p1 of size 15 is
int *p1 [15];
An array of pointers can be defined in such a manner that each item of the array point to an item in the data array. We will illustrate this with a figure.
A B 0 Rajesh 1 Suresh 2 Aneesh 3 Hridaya 4 Joseph 5 Fransis 6 Kannan
Now A is the array of pointers, pointing to the data array B. Instead of sorting B in alphabetical order, we just sort A in the alphabetical order of elements of B and access elements of B from elements of A. This type of sorting has the following advantages.
1. The original data is not changed
2. We save time, because sorting of pointers is simple, compared to sorting of strings.
3. No additional space required.
Program illustrates the use of array of pointers. Program1.6
# include<stdio.h> main() { Char *p [4]; p[0]=”Sunil”; p[1]=”Raj”; p[2]=”Alok”; p[3]=”Syam”;
Printf (“content of pointer 1 is=%s\n”, p [0]); Printf (“content of pointer 2 is=%s\n”,p[1]); Printf (“content of pointer 3 is=%s\n”,p[2]); Printf (“content of pointer 4 is=%s\n”,p[3]); getch();
}
Output of the program content of pointer is 1=Sunil content of pointer is 2=Raj content of pointer is 3=Alok.
1.14 Pointer to Pointer
A pointer to pointer is a form of multiple indirections.
The first pointer holds the address of the second pointer and the second pointer points to a variable.
Pointer pointer Variable.
The general Syntax for the declaration: <Data type> **<pointer name> Eg: int **p1;
Program1.7 #include <stdio.h> main() { int v; int *p1,**p2; v=50; printf("number is =%d\n",v); p1=&v; p2=&p1;
printf("address of the number is = %u\n",&v); printf("value pointed by pointer2 =%u\n",*p2); printf("value of pointer1 =%u\n",p1);
printf("Value pointed by pointer1=%d\n",*p1);
printf("Value pointed by the pointer pointed by pointer2=%d\n",**p2); }
Output of the program number is =50
address of the number is = 4277627172 value pointed by pointer2 =4277627172 value of pointer1 =4277627172
Value pointed by pointer1=50
Value pointed by the pointer pointed by pointer2=50
1.15 Pointers to strings
String operations in c are mainly performed with the help of pointers. String is a sequence of characters; string is accessed in a strictly sequential manner. That is why we use pointers in string operation. String always terminated by a Null character or ‘\0’.
The following program is an example Program for pointers to strings
Program1.8 #include<stdio.h> #define maxsize 60 void main() { char s[maxsize];
printf(“enter the string:”); gets(s);
display(&s);// calls the function printf(“\n”); getch(); } void display(char *s) { while(*s!=’\0’) { printf(“%c”,*s); s++; } }
Output of the program
enter the string: pointers to string pointers to string
Pointer to Functions
Just like any other variable,a function is also stored at a memory location and has an address. The name of the function is a pointer to it. We can also declare pointer to a function.
The following program illustrates an example for function pointer.
Program1.9 #include <stdio.h> void sampleFunction(int n) { printf( "%d\n", n ); } int main() {
void (*pointer_to_function)(int);//Declaring a function pointer
pointer_to_function = &sampleFunction;//Intitialising the function pointer pointer_to_function( 10 );// calling the function using the function pointer
getch(); return 0; }
Output of the program 10
Exercises
1. Explain the pointer declaration in C language. 2. How do you declare a pointer to a function? 3. Explain dereferencing operator.
4. What is a void pointer?
5. How can we access a one dimensional array using pointer? 6. Explain pointers to strings.
7. Explain the different types of recursion. 8. Explain pointer arithmetic with example. 9. How can you create array of pointers?
10. Explain about addressing and dereferencing operators.
Chapter II
Structures And Unions
2.1 Definition
A structure is used to represent a related group of items. Each individual item in the structure is called as a member. Example: struct employee { char empName[10]; char address[20] ; char place[10]; int pinCode; } emp1;
Declares a structure variable emp1 of the type employee. Also the same declaration can be written as
struct employee { char empname[10]; char address[20] ; char place[10]; int pincode; };
struct employee emp1;
Also the type definition can be used to define a structure.
2.2Accessing the members of a structure
To access the members of a structure the
‘.’
operator is used. Example:emp1. 2.3 Array of structures
Suppose you want to store the details of 100 students in an array. Each student has a roll no. and name and the structure student is defined as,
struct student {
int Roll no; Char Name[20]; };
Now you can declare an array of size 100 as shown below: Student NRoll [100];
Each element of the array can be the details of the student. That is an array of structures can be used just like an ordinary array, to store data having structure.
Program illustrates the use of array of structures. Program2.1 #define max 3 #include<stdio.h> void main () { structure student { char name[20]; int Rollno; };
struct student class[max]={{“Ramya”,23},{“Sita”,45},{“Geeta”,47}}; int i;
printf(“List out the contents of Structure\n”); for(i=0;i<=max-1;i++)
{
printf(“Roll no:%d\n”,class[i].Roll no); }
}
Output of the program
List out the contents of Structure Ramya 23 Sita 45 Geeta 47
2.4 Structures Within Structure (Nested Structure) Definition:
A structure having another structure as a member is called a nested structure.
A member of structure may be another structure. When a structure is declared as the member of another structure we call it as nested Structure. Using this feature we can build complex structures. Example: struct date { int day; int month; int year }; struct student { char name[20]; int roll no;
struct date dob; };
2.5 Pointer to Structures
We can declare pointers to structures the same way we declare any other pointers: by preceding the variable name with an asterisk in the declaration.
struct Complex { int x; float y }; struct complex *p1,*p2;
In the above declaration p1, p2 are pointer variables holding the address of a variable of type structure complex.
2.6 Structure in Functions
We can pass a structure variable as a parameter to a function just as we pass any other variable. The following program is an example for passing a structure as a parameter to a function.
Program2.2
#include<stdio.h>
struct dob //Declaring a structure { int day; int month; int year; }; void main() {
struct dob d1; //Declaring a structure variable d1.day=26; d1.month=8; d1.year=2007; display(d1); getch(); }
void display (struct dob n); {
printf(“date is%d/%/d/%d\n”,n.day,n.month,n.year); }
Output of the program date is 26 /8/ 2007
2.7 Unions
We have a situation where we want to interpret the value of a variable depending upon the context of the variable. Union stores values of different data types in a single location. This saves memory. Declaration and usage of union is same as that of structure with the keyword struct replaced by the keyword union.
For example a merchant may sell items by number or by weight (example: two bottles of squash and 3.5 k.g sugar).In this case the field quantity
sold can be taken as a union of an integer and a float. . Declaration union quantity { int no_of_items; float weight; } ; struct saledetails { int type;
union quantity quantity_sold; };
Program to illustrate union
Program 2.3 #include<stdio.h> typedef union { int trucknumber; char truckname[8]; }load; typedef struct { char itemname[10]; load item; }goods; int main() { goods gd[10]; int i,n;
printf ("Enter no of shipping items\t"); scanf("%d",&n);
for (i=0; i<n; i++) {
printf("Enter the itemname ,trucknumber\t"); scanf("%s",gd[i].itemname); scanf("%d",&gd[i].item.trucknumber); } for (i=0;i<n;i++) { printf("\nItemname=%s",gd[i].itemname); printf("\nTruckNumber=%d",gd[i].item.trucknumber); } printf("\n");
for (i=0; i<n; i++) {
printf("Enter the truckname\t"); scanf("%s",gd[i].item.truckname); } for (i=0;i<n;i++) { printf("\nTruckname=%s",gd[i].item.truckname); printf("\nTruckNumber=%d",gd[i].item.trucknumber); } getch(); return 0; }
Output of the Program Enter no of shipping items 2
Enter the itemname ,trucknumber Steel 5678 Enter the itemname ,trucknumber Nickel 6665
Itemname=Steel TruckNumber=5678 Itemname=Nickel TruckNumber=6665
Enter the truckname Bangar Enter the truckname Star7
Truckname=Bangar
TruckNumber=1735287106 Truckname=Star7
TruckNumber=1918989395
In the above program you can see that when we try to print the truck number after reading truck name it is showing some unknown value. This is because the same space is used for storing truck number and truck name. So truck name overwrites the truck number.
2.8 Difference and similarity between structure and union
The differences between structure and union in c are:
3. Union allocates the memory equal to the maximum memory required by any member of the union, but structure allocates the memory equal to the total memory required by all the members.
2. In union, one block is used to store all the members of the union. That is, all the members share same memory. In the case of a structure, each member has their own memory space.
The similarities between structure and union are
2. Their declarations have similar syntax.
2. Accessing members also have the same syntax (using the . Operator)
3. Structures as well as unions can be nested inside other structures or unions.
Exercises
1. Explain the declaration and initialization of structures. 2. Explain structure within structure.
3. Explain the use of pointers in structure. 4. Explain union.
5. What is the difference between structure and union? 6. What you mean by array of structure?
7. Develop a c program to read the following information from the key board • Employees name
• Employees code • Age
• designation
and represent it as a structure.
Chapter III
Strings and String Operations
3.1 Strings
In C, a string is viewed as an array of characters. A special character called null denoted by “\0” ends the string.
The following is an example of a string stored as an array of characters. I LO VE I N D I A \0
C provides for many strings operators. Let us discuss the following in detail.
Function Parameters Use
strlen String Length of string
strcat String1, string 2 Concatenate of string 2 to 1 strcmp String 1, string2 Compare two strings
strcpy String 1, string2 Copy string 2 to string 1
3.2 strlen ( )
We are using strlen() for knowing the length of the string. The strlen ()checks each array position to see whether it is null or not.
N=strlen (string);
Sample program to check the length of the string is given below Program 3.1
#include < stdio.h > #include < string.h> void main() { char name[100]; int length;
printf(“Enter the string=”); gets(name);
length=strlen(name);
printf(“\nNumber of characters in the string is=%d”,length); }
Output of the program Enter the string= Geetha
Number of characters in the string is=6.
Implementation of string length operations using user-defined functions is as follows.
int strlen(char s1[ ]) { int k; for(k=0;s1[k]!=’\0’;k++) { continue; } return(k); } 3.3 strcmp()
This function is used to compares two strings. This function returns value 1 if the two strings are same and it will returns 0 otherwise. This is one of the most commonly used of the string handling functions.
Example:
strcmp(char *a1, char *a2);
Implementation of string comparison operations using user-defined functions is as follows.
int strcmp(char a1[ ], char a2[ ]) { int j,j1,j2; j1=strlen(a1); j2=strlen(a2); if (j1!=j2) return(0); for(j=1;j<j1,j++) { if(a1[j]!=a2[j]) return(0); } return(1); } 3.4 strcat() strcat (string1,string2)
string1 and string2 are strings. When the function strcat is executed string2 is appended to string1. The string at string2 remains unchanged.
strcpy (string1,”sri”); strcat (string2,”devi”);
printf (“%s”,strcat(string1,string2);
From the above program segment the value of string1 becomes sridevi string at str2 remains unchanged as devi.
The following shows the implementation of strcat as a program Program3.2 #include<stdio.h> void main() { char s1[10 ],s2[10 ],s3[30]; int k=0,k1;
printf("Enter the first string\n"); gets(s1);
printf("Enter the second string\n"); gets(s2); for(k=0;s1[k]!='\0';k++) s3[k]=s1[k]; k1=k; k=0; for(k=0;s2[k]!='\0';k++) s3[k1+k]=s2[k]; k1=k1+k;
printf("The concatenated string is given below\n"); for (k=0;k<k1;k++)
printf ("%c",s3[k]); getch();
}
Enter the first string Good morning
Enter the second string India
The concatenated string is given below Good morning India
3.5.strcpy()
This is used to copy one string to another char *strcpy(char *s4, char *s5);
Copy the string pointed to by s5 into the string pointed to by s4,
C does not allow you to assign the characters to a string directly as in the statement Name=”sandya”; instead use strcpy like this
strcpy (Name,”sandya”);
In the above example sandya is assigned to the string called Name.
Implementation of string comparison operations using user-defined functions is as follows.
void strcpy(s,s1) { int k; char s[],s1[]; for(k=0;s1[k]!=”\0”;k++) { s1[k]=s[k]; }
s1[k]=”\0”; }
3.6 Pattern Matching
Pattern matching in strings is the process of checking whether a given pattern of letters (string) occur as a substring in a given string. Here we have two inputs the given string, and the pattern string. Clearly the length of the pattern should not exceed the length of the given string.
3.7 Dynamic Memory Allocation
The C compiler needs to allocate memory to variables. This Memory allocation can be classified into two types.
1. Static or compile time and 2. Dynamic or run time.
In static memory allocation memory required for a variable is allocated at the time for compilation.
For example, if you declare x as a float variable by float x;
Then the memory required for x is the size of a float and allocated at the time of compilation. Similarly if you want to declare an array of 10 integers by
int a [10];
Then 10 times size of an integer is reserved at the compile time. This has the following disadvantages.
1. You cannot use more memory than what you have already allocated.
2. If you use less memory than allocated, the remaining memory is wasted. This causes inefficient use of memory.
Dynamic memory Allocation allocates memory at run time.
The following functions are used in C to do the dynamic memory allocation. malloc, calloc, realloc, free.
3.8 Malloc
This function is used to allocate a heap of storage. The name stands for memory allocation. The general declaration of malloc function,
char *malloc (size) int size;
The following program segment illustrate the use of malloc function struct linkedlist
{
int value
struct linkedlist *value; };
struct linkedlist *pnode;
pnode=(struct linkedlist*)malloc (sizeof(struct linkedlist));
3.9 Calloc
Calloc is used to allocate contiguous memory on an element-by-element basis. The name stands for calculated allocation. This is useful in the case of array like structure where continuity of memory required.
void calloc(elements, element_size);
Thus to assign 500 integer elements that are all initially zero you would do: int *pnode ;
pnode = (int *) calloc(500, size of(int));
The following program illustrates the dynamic allocation of arrays using calloc Program 3.3
#include<stdio.h> int main() {
int *array,n,i;
printf("Enter the size of array\t"); scanf("%d",&n); array=(int*)calloc(n,sizeof(int)); printf("Enter %d numbers\n",n); for(i=0;i<n;i++) scanf("%d",&array[i]); printf("Numbers Entered \n"); for(i=0;i<n;i++)
printf("%d\t",array[i]); getch();
return 0; }
Ouput of the Program Enter the size of array 10 Enter 10 numbers 19 29 39 495 96 97 98 90 80 79 Numbers Entered 19 29 39 495 96 97 98 90 80 79 3.10 Realloc
Realloc is a function which attempts to change the size of a previously allocated block of memory. (Realloc stands for reallocate) The new size can be larger or smaller. If the block is made larger then the old contents remain unchanged and memory is added to the end of the block. If the size is made smaller then the remaining contents are unchanged
The general declaration for the realloc function is given below char *realloc (oldblocksize,newblocksize)
int oldblocksize; int newblocksize;
3.11 Freeing Memory
Memory allocated with malloc lasts as long as you want it.When you have finished using a portion of memory you should always free(deallocate) it. If you want to deallocate the memory that allocate by malloc function call, we can usefunction
free ().
The general declaration for free () function is given below int free (pnode)
char *pnode;
The following program illustrates the use of malloc( ) to allocate some bytes then use realloc( ) to allocate more bytes and finally use free( ) to deallocate the allocated bytes.
Program 3.4
#include<stdio.h> int main()
{
char *p,size,newsize; printf("Enter the size\t"); scanf("%d",&size);
p=(char *)malloc(size); //allocating size bytes to character pointer p. printf("Enter a string of length %d\t",size);
getchar(); gets(p); puts(p);
printf("Enter the new size\t"); scanf("%d",&newsize);
p=realloc(size,newsize); //reallocating newsize bytes to character pointer p. printf("Enter a string of length %d\t",newsize);
getchar(); gets(p); puts(p);
free(p); //deallocating memory. printf("Memory is deallocated\n"); getch();
}
Output of the program Enter the size 5
Enter a string of length 5 abcde abcde
Enter the new size 7
Enter a string of length 7 abcdefg abcdefg
Exercises
1. How we are using pointers to handle strings? 2. What are the different string handlings functions? 3. Write a c program to find out the length of a string.
4. Write a C program to print the string abbreviation of an inputted string. 5. Explain the different types of memory allocation.
6. What is the disadvantage of static memory allocation ? 7. Explain Dynamic memory allocation.
8. What are the advantages of dynamic memory allocation?
9. How can you change the size of previously allocated memory? 10.How can you deallocate a memory?
Chapter IV
Sorting and Searching
4.1 Sorting
Sorting is arranging data items in some order.
For example, we may want to arrange 10 numbers in ascending (increasing) order, or a teacher may need to arrange a list of students in alphabetical order, or he may want to arrange the marks of students in descending (decreasing)order. For all such purposes we use sorting.
Example:
The numbers 9,10,5,6,3,8 when sorted in ascending order becomes 3,5,6,8,9,10, and when sorted in descending order, they are arranged as 10,9,8,6,5,3.
There are two types of sorting 1. Internal sorting.
2. External sorting. 1. Internal sorting:
This means data for sorting is available in memory. 2. External sorting:
Some times it happens that data item for sorting is too large to occupy in memory. So we need to store such items in secondary storage devices then we have to apply external sorting.
4.2 Different Sorting Techniques
1. Bubble sort
It is the oldest and simplest sorting technique. In bubble sort pairs of adjacent values are sorted by comparing the values with each other. Therefore an item bubbles the entire list, until it reaches one value that compare to be smaller than the first value. Suppose we have an n number of elements in our list to sort, then we have to do (n-1) passes (iterations).
Advantages:
Bubble sort is simple and easy to implement.
Disadvantages:
For n no of elements there will be n-1 iterations. So Bubble sort is considered as the most inefficient sorting algorithm.
Best case:
Under best case if array is already sorted then also the outer loop to execute n-1 times. Time complexity for best case is O (n2
).
4.3 Bubble sort implementation
In order to explain bubble sort we are taking an array of three items. This is shown below.
a[0] 160
a[1] 155
a[2] 120
3. In first iteration i=0, 0th element 160 is compared with 155. Since 160 is greater than 155, we interchange them. Resulting array is 155,160,120.
Now 160 is in a[1]th position. It is compared with the a[2].120 is less than 160, so we interchange them. Array is now 155,120,160
2. For the second iteration 0th element 155 is compared with first element. Here 120 is less than 155, so we interchange them. Resulting array is 120,155,160.Now 155 is in a [1], it is compared with a[2].155 is less than 160,we cannot interchange them. Now the array is in its sorted order. Resulting array is 120,155, 160.
a[0] 120
a[2] 160
Program for bubble sort: Program 4.1 #include<stdio.h> #include<conio.h> void main() { int i,j,n,array[5],tempvalue=0; printf("Enter the size\n"); scanf("%d",&n); printf("Enter %d numbers\n",n); for(i=0;i<n;i++) { scanf("%d",&array[i]); } for(i=0;i<n;i++) { for(j=0;j<n-1;j++) { if(array[j]>array[j+1]) { tempvalue=array[j]; array[j]=array[j+1]; array[j+1]=tempvalue; } } }
printf("The list sorted in ascending order is\n"); for(i=0;i<n;i++) { printf("%d\n",array[i]); } getch(); }
Ouput of the Program Enter the size
5 Enter 5 numbers 99 77 88 66 55
The list sorted in ascending order is 55 66 77 88 99 4.4. Selection sort
In selection sort we are taking the smallest item (unsorted) in the list, and swapping it with the item in the very next position. Suppose we want to sort the given numbers in ascending order, 0th element is compared with other elements present in the list, .If the 0th element is greater than the compared element then they are interchanged. After the first iteration the smallest element is placed in 0th position. Similar procedure is repeated for the entire list of elements.
Advantages:
Simple technique and easy to implement. Disadvantages:
Inefficient for large list of elements. Program for selection sort 4.5 selection sort implementation
We can explain the selection sort by taking an array of 4 items.
a[0] 250
a[1] 150
a[2] 200
a[3] 100
2. For the first iteration i=0, 0t h element is compared with a[1]. 150 is less than 250, we interchange them. Resulting array is 150 250 200,100.a[0]t h element is again compared with a[2]th element, which is greater than a[0]th element so we can’t interchange them. Again 150 compared with a[3].100 is less than 150, we interchange them. The resulting array is 100,250,200,150.
3. For the second iteration i=1, a [1] th element compared with a [2]. 200 is less than 250, we interchange them. Resulting array is 100,200,250,150.
a [3]th element compared with a[1]. 150 is less than 200, we interchange them. Resulting array is 100,150,250,200.
3. For the third iteration i=2,250 is compared with a [3]. 200 is less than 250 we interchange them. Resulting array is
a[0] 100
a[1] 150
a[2] 200
a[3] 250
Program for selection sort Program 4.2
void main() {
int array[12],i,n,smallvalue,j,position,tempvalue; printf("Enter the size\n");
scanf("%d",&n); printf("enter %d elements\n",n); for(i=0;i<n;i++) scanf("%d",&array[i]); for(i=0;i<n-1;i++) { smallvalue=array[i]; position=i; for(j=i+1;j<n;j++) { if(array[j]<smallvalue) { smallvalue=array[j]; position=j; } } tempvalue=array[i]; array[i]=smallvalue; array[position]=tempvalue; }
printf("\n Sorted array is\n"); for(i=0;i<n;i++) { printf("%d\n", array[i]); } getch(); }
Output of the Program
Enter the size 5 enter 5 elements 99 66 33 88
77 Sorted array is 33 66 77 88 99 4.6. Insertion sort
Insertion sort is a simple sorting algorithm, in which the sorted array (or list) is built one entry at a time. The insertion sort works just like its name; it inserts each item into its proper place in the list. We use two lists to implement insertion sort. The insertion sort has a time complexity of O (n2).
Advantage:
Comparatively simple and it is easy to implement. Disadvantage:
Inefficient for large lists.
4.7. Insertion sort implementation
Here we have an array a[3], consists of 3 elements. We can see how insertion sort is going to implement for sorting numbers in ascending order.
a[0] 160
a[1] 152
a[2] 100
interchange them.
2. For the second iteration i=2, the second element 100 is compared with 160. Then we interchange them.100 is again compared with 152. The resulting Array is shown below.
a[0] 100
a[1] 152
a[2] 160
Program for Insertion sort: Program 4.3
#include<stdio.h> void main()
{
int array[12],i,j,n,tempvalue;
printf("Enter the size of numbers to sort\n"); scanf("%d",&n); printf("enter %d numbers\n",n); for(i=0;i<n;i++) scanf("%d",&array[i]); for(i=1;i<n;i++) { tempvalue=array[i]; j=i-1; while((tempvalue<array[j]&&(j>=0))) { array[j+1]=array[j]; j=j-1; } array[j+1]=tempvalue; } printf("Sorted array is \n"); for(i=0;i<n;i++) printf("%d\n",array[i]);
getch(); }
Output of the Program
Enter the size of numbers to sort 5 enter 5 numbers 99 22 55 77 44 Sorted array is 22 44 55 77 99 4.8Quick sort
The quick sort is one of the fastest sorting techniques. Quick sort is an algorithm using recursion. There are four steps in the algorithm.
If there are no elements or just one element in the array to be sorted, return immediately.
1. Select an element in the array as a “pivot” point. Mainly we are taking the leftmost element in the array
2. Split the array into two parts - one with elements larger than the pivot and the other with elements smaller than the pivot.
3. Repeat the algorithm for both halves of the original array.
The efficiency of the algorithm mainly depends upon which element is chosen as the pivot element. The worst-case efficiency of the quick sort, O (n2
), occurs when we have taken the left-most element. As long as the pivot point is chosen randomly, the quick sort has its algorithmic complexity of O (n log n).
Advantage:
Extremely fast one. Disadvantage:
4.9 Quick sort implementation
We can explain the Quick sort by the following example. We have an array of 7 Elements. a[0] 56 a[1] 12 a[2] 25 a[3] 33 a[5] 100 a[6] 70 a[7] 80
There are a number of ways to pick the pivot element. In this example, we will use the first element in the array as pivot element.
Given a pivot, partition the elements of the array such that the resulting array consists of: 3.1. One sub-array that contains elements >= pivot
3.2. Another sub-array that contains elements < pivot
Quick sort starts with 0th element 56. Read the elements from right to left. Compare element with 56 on starting from right to left. Stop at the element which has
less value of that 56. The number is 33, we interchange them. Resulting array look like this
33 12 25 56 100 70 80.
We take 56 as the Pivot element. Because the elements of the array to left are smaller than 56; elements of the array to right are greater than 56. Here we are dividing the array into two parts, one is right side of 56, other one is left side of 56.The above procedure is repeated for the two sub arrays, until we get the sorted array.
Program for Quick sort Program 4.4 #include<stdio.h> int main()
{
int array[30],n,i;
printf("\nEnter size of the array :"); scanf("%d",&n);
printf("Enter %d elements : ",n); for(i=0;i<n;i++) // reading elements scanf("%d",&array[i]);
quickSort(array,0,n-1);// function to sort printf("\nSorted elements :"); for(i=0;i<n;i++) printf(" %d",array[i]); getch(); return 0; }
quickSort(int array[10],int left,int right) {
int pivot,j,temp,i; if(left<right)
{
pivot=left; //choosing first element as pivot i=left;
j=right;
/*Considering the pivot element array is subdivided into two arrays*/ while(i<j) { while(array[i]<=array[pivot]&&i<right) i++; while(array[j]>array[pivot]) j--; if(i<j) { temp=array[i]; array[i]=array[j]; array[j]=temp; } } temp=array[pivot]; array[pivot]=array[j]; array[j]=temp;
quickSort(array,left,j-1); //applying quick sort to left sub array quickSort(array,j+1,right); //applying quick sort to second sub array }
}
Output of the program
Enter size of the array :10
Enter 10 elements : 88 55 99 22 44 66 11 43 57 21 Sorted elements : 11 21 22 43 44 55 57 66 88 99
4.10.
Merge SortMerge sort is another sorting algorithm which works in the following way. 3. Divide the element in to two parts.
4. Sort the two parts using merge sort algorithm 5. Merge the two sorted list in to a single sorted list.
The heart of a merge sort algorithm is a procedure to merge two sorted list in to a single sorted list. The time complexity of the algorithm is O(nlogn).
Advantage:
Marginally faster for larger sets. Disadvantage:
At least twice the memory requirement of the other sorts:
4.11 Merge Sort Example
Consider an array of 4 integers 7,3,5,4. Now merge sort first divides the array in to two sub array [7,3], and [5,4].In the next step[ 7,3] and [5,4 ] are divided in to [7]&[3] and [5]&[4].Now these two are merged back to form[3,7] and[4,5], which is again merged to form 3,4,5,7. The below figure explains the idea.
Program for Merge sort Program 4.5
#include<stdio.h> #define maxsize 50
void merge( int array1[maxsize],int start1,int end1, int end2) {
//merges two sorted sub arrays array1[start1],..., array1[end1] and //array1[end1+1]...
// array1[end2] into a single sorted array.
int size1,size2,size3, index1,index2,index3, index4,i,j; int result[maxsize]; //A temporary array to store the result index1=start1;
index2=end1+1; index3=start1; index4=start1;
while((index1<=end1)&&(index2<=end2))
if(array1[index1]<array1[index2]) //If an element in the first subarray // is lesser,move it to the result array
{ result[index3]=array1[index1]; index1++; index3++; } else {
result[index3]=array1[index2]; //otherwise move the element of //the second part to the result array
index2++; index3++; }
if(index1>end1) //first part is over.
// So copy the second part to the result array while(index2<=end2)
{
result[index3]=array1[index2]; index2++;
}
else //second part is over while(index1<=end1) { result[index3]=array1[index1]; index1++; index3++; }
for(index4=start1;index4<=end2;index4++) //copy the result array to //corresponding positions in the original array
{
array1[index4]=result[index4]; }
}
void mergesort(int data[maxsize],int start,int end)//sorts elements from positions //start to end in an array using merge sort
{
int mid; if(start<end) {
mid=(start+end)/2;
mergesort(data,start,mid); //first sort the first half mergesort(data,mid+1,end);//now sort the remaining merge(data,start,mid,end);//merge them
} }
void main() {
//program to sort an array of 10 elements using merge sort int A[maxsize], final,i,result,n;
printf("Enter the no. of elements\n"); scanf("%d",&n); result=0; for(i=0;i<n;i++) { printf("Give A[%d]:",i); scanf("%d",&A[i]); } mergesort(A,0,n-1);
printf("\nThe sorted Array is\n"); for(i=0;i<n;i++)
printf("%d\n",A[i]); getch();
}
Output of the Program Enter the no. of elements 7 Give A[0]:12 Give A[1]:45 Give A[2]:89 Give A[3]:32 Give A[4]:1 Give A[5]:4 Give A[6]:55
The sorted Array is 1 4 12 32 45 55 89 4.12. Bucket Sort
Bucket Sort is another approach based on comparing digits. Bucket sort assumes that the range of input is known beforehand .It assumes that the input is uniformly distributed over the range. In this method the range of input is divided in to sub intervals called Buckets and place the input into these buckets. Then these buckets are sorted and listed in order.
Program for Bucket Sort Program 4.6
#include <stdio.h>
void bucketSort(int array[],int n); int main()
{
int n = 10; int i;
printf("The array is\n\n"); for (i = 0;i < n;i++)
printf("%d ", array [i]); printf("\n");
bucketSort(array, n);
printf("The Sorted array is\n\n"); for (i = 0;i < n;i++)
{
printf("%d ", array [i]); } printf("\n"); getch(); return 0; }
void bucketSort(int array [], int n) { int i, j; int a[n]; for(i=0;i<n;i++) { a[i] = 0; } for(i=0;i<n;i++) { (a[array [i]])++; } for(i=0,j=0;i<n;i++) { for(;a[i]>0;(a[i])--) { array [j++] = i; }
} }
Output of the Program The array is
1 7 4 6 4 2 8 1 2 9 The Sorted array is 1 1 2 2 4 4 6 7 8 9
4.13. Heap Sort
Heap sort uses a heap for sorting. A heap is a type of binary tree. It has two properties.
1. It is a complete binary tree. At each level, except possibly the last level, every node has two children.
2. The value of each node is, greater than or equal to the values of nodes in the children. (This is called the heap property)
Algorithm for heap sort contains the following steps: 1. Construct a heap from the array elements.
2. Shift the root element of the heap to the end of the array, and then rebuild the heap structure with the remaining elements.
3. Repeat step 2 until there are no more elements in the heap. The time complexity of heap sort is O(nlogn).
Figure for heap Program for HeapSort
Program 4.7
#include<stdio.h> #include<conio.h>
void heapsorting(int [ ],int); void main()
{
int w[25],i,n;
printf("Enter the no of elements to sort\n" ); scanf("%d",&n);
printf("Enter %d elements to sort\n",n); for(i=0;i<n;i++ )
scanf("%d",&w[i]); heapsorting(w,n);
printf("\nAfter the heap sort\n"); for(i=0;i<n;i++)
printf("\t%d",w[i]); getch();
}
void heapsorting(int x[ ],int n) {
int i,el, s1,f1,evalue; for(i=1;i<n;i++) { el=x[i]; s1=i; f1=(s1-1)/2; while(s1>0&&x[f1]<el) { x[s1]=x[f1]; s1=f1; f1=(s1-1)/2; } x[s1]=el; } for(i=n-1;i>0;i--) { evalue=x[i]; x[i]=x[0]; f1=0; if(i==1) s1= -1;
else s1=1; if(i>2&&x[2]>x[1]) s1=2; while(s1>=0&& evalue<x[s1]) { x[f1]=x[s1]; f1=s1; s1=2*f1+1; if(s1+1<=i-1&&x[s1]<x[s1+1]) s1=s1+1; if(s1>i-1) s1= -1; } x[f1]=evalue; } }
Output of the Program
Enter the no of elements to sort 7
Enter 7 elements to sort 99 77 33 55 88 22 44
After the heap sort 22 33 44 55 77 88 99
4.18 Compare Different Sorting Algorithms
We have seen different sorting and searching algorithms. Depending up on the types of data and the operation one may perform on data, we are choosing different sorting algorithm.
We compare algorithms based on time complexity .The time complexity of algorithm measures the running time of the algorithm compared to the input data.
Time complexity is represented using the O notation. An algorithm is O(n) if the running time is less than or equal to a constant times n. Here n is the size of the input. Similarly an algorithm is O (n2) if
it’s running time less than or equal to a constant time n2, and so on. And O(n) algorithm is considered
better than O (nlogn) algorithm, which in turn is consider better than an O(n2) algorithm and so on.
We can see the time complexity for different algorithms
Algorithm Worst case Average case Bubble sort O(n2) O(n2)
Insertion sort O(n2) O(n2)
Selection sort O(n2) O(n2)
Merge sort O(n log n) O(n log n) Quick sort O(n2) O(n log n) Heap sort O( n log n) O(n log n)
From the above comparison it is clear that
1. Bubble sort, selection sort and insertion sort have the same time complexity O(n2
). Also bubble sort is easy to implement, But is highly inefficient.
2. Quick sort and heap sort have the same average time complexity O(nlogn). So both of them are considered better than Bubble sort, selection sort or insertion sort. The choice of the correct pivot point is important in quick sort, But heap sort guarantees O(nlogn) performance under any condition.
3. Merge sort also works in O(nlogn) time, so it is better than Bubble sort, selection sort or insertion sort ,but it works only when the given lists are already sorted.
4. Bucket sort is an O(n) sorting algorithm, So it can be considered better than other algorithms, but it works only when the numbers are uniformly distributed and range of input known in advance.
5. For smaller input simpler algorithms such as bubble sort may be better, but for larger input algorithms like Quick sort and heap sort are better. Also if the input consists of two sorted lists, merge sort is better. If the input is uniformly distributed and ranges of values are known in advance, bucket sort is better.
Searching is the process of determining whether a given element is in a list. A search technique will give the position of the element if one is found. Otherwise it will say that element is not found.
4.15. Linear search
We also call it as sequential searching. In Linear search searching means a set of data for a particular value .We are the entire list one by one until we get the desired value. This is one of the simplest searching Techniques.
Advantage :
Good to use for small sets of data. Disadvantage:
Suppose the data set is too big, then the searching process will be slower.
Program for Linear search Program 4.8
#include <stdio.h> void main()
{
int a[10],i,n,position,n1;
printf("Enter the size of the array\n"); scanf("%d",&n);
printf("Enter the elements\n"); for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("Enter the element to search\n"); scanf("%d",&n1); for(i=0;i<n; i++) { if(a[i]==n1) { position=i;
printf(" Search Successful :Location at %d", position); break;
} }
if(i==n)
printf(" Sorry search unsuccessful"); getch();
}
Output of the Program Enter the size of the array 7
Enter the elements 33 77 22 99 55 44 88
Enter the element to search 99
Search Successfull:Location at 3
4.16 Binary Search
It is a technique to find out a particular value in a sorted list of items. Binary search is a fast and efficient searching technique. In binary search we are comparing the elements with the element in the middle of the list(mid).we are taking the middle element by taking the first and last element of the list Mid= (beg+last) /2.
A fast way to search a sorted array is to use a binary search. We are going to take the element in the middle for seaching purpose. If the element we want to search is equal to mid element, the search is finished. If the element is less than the mid element, we are searching on the first half. If it’s greater, we are searching at the second half.
Advantage:
Fast and easy to implement. Disadvantage:
Works only on sorted array. Program 4.9
#include<stdio.h> void main()
{
int array[10],i,j,t,begin,end,n,middest,num; printf("Enter the size of the array\n"); scanf("%d",&n);
printf("Enter the elements in sorted order\n"); for(i=0;i<n;i++)
scanf("%d",&array[i]); begin=0;
end=n;
printf("Enter the element to search\n"); scanf("%d",&num); while(begin<end) { middest=(begin+end)/2; if(array[middest]==num) {
printf("Search is success element found at location at %d", middest); break; } if(num>array[middest]) begin=middest+1; else end = middest-1; } if(begin==end) printf("unsuccessful search"); getch(); }
Output of the program
Enter the size of the array 10
Enter the elements in sorted order 11 22 33 44 55 66 77 88 99 100 Enter the element to search 77
4.17 Difference between Linear Search & Binary Search
5. We use linear search for a small set of values. But we can use Binary search for a large set of values.
6. On comparing with binary search technique linear search is a slower one.
7. Binary search is applicable in the case of sorted elements only. But using linear search you can find out the element from unsorted list. In the case of an unsorted array linear search is the best one.
Exercises
1. Explain different sorting methods. 2. What is external sorting?
3. Define searching.
4. Compare different searching algorithms. 5. What is time complexity?
6. List out the complexity comparison of different sorting algorithms. 7. Explain quick sort.
8. Write a c program for linear search. 9 Write a c program to implement heap sort. 10. Write a c program to implement bubble sort.
Chapter V
Stacks and Queues
5.1 Stack
Stack is a data structure which uses the principle of Last in first out (LIFO). In stacks we are removing the element that we recently added in to the list. The most recently added item is at the top of the stack. Here insertion and deletion is carried out at one end. Basic stack operations are push and pop.
Insertion of elements in to the stack is known as PUSH operation and deletion of elements from stack is known as POP operation. Stack can represented using both an array and a linked list.
Figure 5.1 Different operations on a stack
Push : Places an object on the top of the stack Pop : Removes an object from the top of the stack Empty : Reports whether the stack is empty or not.
5.2 Implementation of Stack Using Arrays and pointers
Array can be used to represent stacks. On using array limited number of elements can be inserted and deleted. Suppose we have declared an array of stack of size 4
Eg int stack [5], and then we can insert maximum 5 elements, starting from stack [0] to stack [4]. We have a pointer Top which always point to the top element in the stack. Initially we have declared that top as empty, by giving a value (-1).If stack contains single data item top points to stack [0]. When a new element is inserted in to the stacks, top is increments by one. The pointer is decremented by one each time a deletion happens.
Program to implement stacks using arrays Program 5.1
#include<stdio.h> #define Size 4
void pushoperation(); //add item to stack void popoperation(); //delete item from stack void showstack(); //to show stack
int stack[Size],Top=-1; void main() { int option; do {
printf("Which stack operation you want?\n"); printf("1-PUSH\n2-POP\n3-SHOW\n4.Exit\n"); scanf("%d",&option); switch(option) { case 1:pushoperation(); break; case 2:popoperation(); break; case 3:showstack(); break; } }while(option<4); getch(); }
void pushoperation() //add item to stack
{ int v;
if(Top>=Size)
printf(" Sorrry not enough space"); else
{
printf("Please enter the element in to the stack\n"); scanf("%d",&v); Top=Top+1; stack[Top]=v; } }
void popoperation() //delete item from stack
{ int t;
if(Top==-1) {
printf("Sorry stack is empty"); return; } else { t=stack[Top]; Top=Top-1;
printf("%d popped from the stack\n",t); }
}
void showstack() //to show stack
{ int i;
if (Top==-1)
printf("Stack is empty "); else
{
printf("Stack contents are..\n"); for(i=Top;i>=0;i--) { printf("%d\n", stack[i]); } } }
Output of the program
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 1
Please enter the element in to the stack 111
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 1
Please enter the element in to the stack 222
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 1
Please enter the element in to the stack 333
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 3
Stack contents are.. 333
222 111
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 2
333 popped from the stack
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 3
Stack contents are.. 222
111
Which stack operation you want? 1-PUSH
2-POP 3-SHOW 4.Exit 4
Program for implementing stack using pointers:
#include<stdio.h> struct stack
{
int value;
struct stack *link; };
struct stack *pushoperation(struct stack *top,int val); struct stack *popoperation(struct stack *top,int *val); void showstack(struct stack *top);
void main() {
struct stack *top; int val,ch;
top=NULL; do
{
printf("\n Menu for stack operation"); printf("\n 1.Add\n 2.Delete\n 3.Show\n"); printf("\nEnter u r choice\n");
scanf("%d",&ch); switch(ch)
{
case 1:
printf("Enter the element to push in to stack\n"); scanf("%d",&val); top=pushoperation(top,val); break; case 2: top=popoperation(top,&val); if(top!=NULL)
printf("the deleted value is %d",val); break;
case 3:
showstack(top); break;
}while(ch<4); getch();
}
struct stack* pushoperation(struct stack *top,int val) // add item to stack {
struct stack *w;
w=(struct stack*)malloc (sizeof(struct stack)); w->value=val;
w->link=top; top=w;
return(top); }
struct stack* popoperation(struct stack*top,int *val) // Remove item from stack
{
struct stack *w; if (top==NULL) {
printf(" Sorry stack is empty\n"); top= NULL; } else { w=top; top=top->link; *val=w->value; } return(top); }
void showstack(struct stack *top) //Display stack items {
struct stack *p1; p1=top;
printf("contents of stack is\n"); while(p1!=NULL)
{
printf("\n%d",p1->value); p1=p1->link;
} }
Output of the Program Menu for stack operation 1.Add
2.Delete 3.Show
Enter u r choice 1
Enter the element to push in to stack 222
Menu for stack operation 1.Add
2.Delete 3.Show
Enter u r choice 1
Enter the element to push in to stack 333
Menu for stack operation 1.Add 2.Delete 3.Show Enter u r choice 3 contents of stack is 333 222
Menu for stack operation 1.Add
2.Delete 3.Show
Enter u r choice 2
the deleted value is 333 Menu for stack operation