PPS Unit-III
PPS Unit-III
PPS Unit-III
There are different sorting mechanisms: Selection sort, Bubble sort, Merge sort, Heap sort … etc.
SEARCHING
There are two basic searching techniques that can be applied to an array of elements.
The Linear/Sequential search is used whenever the list is not ordered, small in size and not searched too
often.
The Binary search is used, if the list is ordered, large in size and searched too often.
SELECTION SORT:
In the selection sort, the list is divided into two sub-lists, sorted and unsorted, which are divided by an
imaginary wall.
The smallest element from the unsorted sub-list is found and swapped with the element at the beginning of
the unsorted sub-list.
After each selection and swapping, the imaginary wall between the two sub-lists moves one element ahead,
increasing the number of sorted elements and decreasing the number of unsorted elements.
Each time an element is moved from the unsorted sub-list to the sorted sub-list, we call it a sort pass is
completed.
To sort a list of n-elements, n-1 sort passes are needed.
// C program for implementation of selection sort
#include <stdio.h>
void swap(int*,int*);
void selectionSort(int[],int);
void printArray(int[],int);
Output:
Sorted array:
11 12 22 25 64
BUBBLE SORT:
In the bubble sort, the list is divided into two sub-lists, sorted and unsorted.
The smallest element is bubbled from unsorted sub-list and moved to the sorted sub-list.
After moving the smallest element to the sorted sub-list, the imaginary wall moves one element ahead,
increasing the number of sorted elements and decreasing the number of unsorted elements.
Moving one element each time from unsorted sub-list to the sorted sub-list completes one sort pass.
Given a list of n-elements, the bubble sort takes n-1 sort passes to sort the data.
Remember the bubble sort concept starts from the end of the list.
// C program for implementation of Bubble sort
#include <stdio.h>
void swap(int*, int*);
void bubbleSort(int[],int);
void printArray(int[],int);
int main()
{
int list[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(list)/sizeof(list[0]);
bubbleSort(list, size);
printf("Sorted array: \n");
printArray(list, size);
return 0;
}
LINEAR/SEQUENTIAL SEARCH
In sequential search, the searching for the target will start from the beginning of the list, and will continue
until the target is found or until the end of the list is reached (no target found case).
Example:
The following figure lists the steps to find 62. The process will first compare the value with data at index 0,
then 1, 2, and 3 before finding the element at 5th location (index 4).
If the target value is not in the list, then the comparison operation will reach the end of the list, making sure
that the target is not in the list. The figure also lists the steps for finding the value 72, which is not there in
the list.
// C-Program for Linear Search.
#include<stdio.h>
int seqSearch(int[],int,int);
int main(void)
{
int list[20], target, index, i, size;
system("cls"); //clrscr();
printf("Enter the size of the list:");
scanf("%d", &size);
printf("Enter any %d elements:\n", size);
for (i = 0; i < size; i++)
scanf("%d", &list[i]);
if (index==-1)
printf("%d isn't present in the list.\n", target);
else
printf("%d is present at index %d in the list",target, index);
getch();
return 0;
}
BINARY SEARCH
How it works:
The binary search starts by comparing the data in the element in the middle of the list. This determines if
the target is in the first half or second half of the list.
If the target is in the first half, no need to search the second half and if the target is in the second half, then
no need to search the first half.
Either way half of the list will be eliminated from consideration.
The same process will be repeated until the target is found or it’ll be confirmed that the target is not in the
list.
The two important cases in binary searching process are:
o The target found case.
o The target not found case.
To find the middle of the list, we need three variables, one to identify the beginning of the list (first), one to
identify the middle of the list (mid), and one to identify the end of the list (last).
Target Found:
The following figure shows finding 22 in a sorted list. In our case first will be 0 and last will be 11 and mid
can be calculated as follows.
mid = (first + last) / 2;
Since the index mid is an integer, the result of will be an integral value: mid = ( 0 + 11 ) / 2 = 11 / 2 = 5
At index location 5, the target is greater than the list value ( 22 > 21 ). Therefore the list location from 0
through 5 can be eliminated.
Now in the step the first will be made as: first = mid + 1 i.e. first = 5 + 1 = 6. And further calculates the mid
by using same formulae: mid = (first + mid)/2 i.e. mid = ( 6 + 11 ) / 2 = 17 / 2 = 8.
Again the target will be tested with value at mid, this time the target is less than the list value ( 22 < 62 ).
This eliminates locations 8 through 11.
This time last will be adjusted as: last = mid – 1 i.e. last = 8 – 1 = 7 and mid = ( first + last ) / 2 = ( 6 + 7 ) /
2 = 6.
Now at mid location the value matches with the target. This will stop the search.
The target not found in the binary search is something when we searched all the possibilities and didn’t
find the target in the list.
This is done in the binary search when first becomes greater than last.
Thus only two conditions terminate the binary search algorithm: Either the target is found or first
becomes larger than last.
//Binary Search algorithm
#include <stdio.h>
int binSearch(int[],int,int);
int main(void)
{
int i, index, size, target, list[20];
system("cls"); //clrscr();
printf("Enter size of the list:");
scanf("%d",&size);
printf("Enter any %d elements:\n", size);
for(i = 0; i < size; i++)
scanf("%d", &list[i]);
printf("Enter target value:\n");
scanf("%d", &target);
index=binSearch(list,target,size);
if(index==-1)
printf("%d isn't found in the list",target);
else
printf("%d is fount at %d in the list",target,index);
getch();
return 0;
}
FUNCTIONS:
The programs we have presented so far have been very simple. They solved problems that could be
understood without too much effort.
As the program size grows and it is common practice to divide the complex program into smaller
elementary parts.
The planning for large programs is simpler. First we must understand the problem as a whole; then break it
into simpler and smaller understandable parts. We call each of these parts of a program a module and
subdividing a problem into manageable parts top-down design.
The technique used to pass data to a function is known as parameter passing.
Functions in C:
In C, the idea of top-down design is done using functions. A C program is made of one or more functions,
but one and only one of which must be named main.
The execution of the program always starts and ends with main, but it can call other functions to do some
of the job.
A function in main including main is an independent module that will be called to do a specific task. A
called function receives control from calling function.
When the called function completes its task, it returns control back to the calling function. It may or may
not return a value to the caller.
The function main is called by the operating system; main in turn calls other functions. When main is
complete, control return to the operating system.
In general, the purpose of a function is to receive zero or more pieces of data, operate on them, and return
at most one piece of data.
Like every other object in C, functions must be declared, defined and called when needed.
The function declaration needs to done before the function call, mentions the name of the function, the
return type and type and order of the formal parameters. The declaration uses only the header of the
function and ended with a semicolon.
The function definition can be coded after the function call contains the code needed to complete the task.
The function call comes within a function which calls it to get the portion of the job to be done.
A function name is used three times: for declaration, in a call and for definition.
Example programs:
void greetings()
{
printf("Hello World\n");
}
Output:
Hello World
The classification of the basic function designs is done by their return values and their parameter list.
Functions either return a value or don’t. Functions that don’t return a value are known as void functions.
Based on requirement parameter list is also optional. Either they can have parameters or don’t.
Combining the return values and parameter lists functions can be classified into four basic designs:
1. void functions without parameters
2. void functions with parameters
3. non void functions without parameters
4. non void functions with parameters
void add(void)
{
int a=10,b=20,sum;
sum=a+b;
printf("Sum of %d,%d is:%d",a,b,sum);
}
Output:
Sum of 10,20 is:30
This type of functions returns a value but don’t have any parameters.
The most common use of this design reads data from the keyboard or file and returns to the calling
function.
As this function returns a specific type of value, the function call must be initialized with variable of that
specific type.
int add()
{
int a=10,b=20,sum;
sum=a+b;
return sum;
}
Output:
Sum of a,b is:30
//Programs for getValue() function
#include <stdio.h>
int getValue(void);
void main(void)
{
int val1,val2;
val1=getValue();
val2=getValue();
printf("Val1:%d, val2:%d",val1,val2);
}
int getValue(void)
{
int val;
printf("Enter Value:");
scanf("%d",&val);
return val;
}
Output:
Enter Value:24
Enter Value:36
Val1:24, val2:36
o Like every other object in C, functions must be declared, defined and initialized (calling of the function).
o The functions defined by the user who is writing the program, but not by the developers of the language are
known as user defined functions.
o To use functions in a C-Program one has to do, the declaration, definition and initialization of the function.
o The function declaration has to be done before function call, which will give the complete picture of the
function.
o And definition will succeed function call, which actually contains the statements (body) of the function.
Function Declaration:
o Function declaration consists of only a function header. It contains no code (body of the function).
o Function declaration consists of three parts: the return type, the function name and the formal parameter
list.
o Function declaration will be terminated by a semicolon.
o The return type is the type of value the function is going to return after performing its job. If there is no
return type the type will be void type.
o In declaration the parameter list will indicate only the valid type and order of the parameters; the variable
identifier can be omitted here in this case.
o Generally the declarations are placed in the global declaration area of the program. That is before the main
function.
Function call:
Function Definition:
function header
A function header consists of three parts: the return type, the function name, and the formal parameter list.
A semicolon is not required at the end of the function definition header.
The return-type should come before the function name; return-type specifies the type of value a function
will return. If the function has nothing to return, the return type will be void.
The formal parameter list must match with the type and order of the actual parameters. Here while
specifying the formal parameters the variable identifier is must, which will hold the values passed by actual
parameters.
function body
The function body contains the local declarations and the function statements.
The body starts with local definitions that specify the variables needed by the function. After local
definition, the function statements, terminating with a return statement.
If a functions return type is void, it can be written without a return statement.
In the definition of a function, the parameters are contained in the formal parameter list.
This list declares and defines the variables that will contain the data received by the function.
If the function has no parameters; if it is not receive any data from the calling function, then the parameter
list can be void.
Local Variables:
A local variable is a variable that is defined inside a function body and used without having any role in the
communication between functions.
int getvalue()
{
int temp;
printf("Enter value:");
scanf("%d",&temp);
return temp;
}
Inter function communication is a concept through which calling function and called function will
communicate with each other, and exchange the data.
The data flow between the called and calling function can be divided into three strategies:
I. Downward flow
II. Upward flow
III. Bi-directional flow
I. Downward flow:
In downward communication, the calling function sends data to the called function.
No data flows in the opposite directions.
The called function may change the values passed, but the original values in the calling function remains
untouched.
The pass by value or call by value mechanism is a perfect solution for downward flow.
A variable is declared and defined in the called function for each value to be received from the calling
function.
Downward communication is one-way communication. The calling function can send data to the called
function, but the called function cannot send any data to the calling function.
//downward communication
#include<stdio.h>
void downFun(int,int);
void main(void)
{
int a=5;
downFun(a,15);
printf("Value of a is:%d",a);
}
Upward communication occurs when the called function sends data back to the calling function without
receiving any data from it.
C provides only one way for upward flow, the return statement.
Using return statement only one piece of data item can be returned.
To send multiple values back to the calling function, we have to use references of variables. References are
memory locations which carries the data from called function to the calling function.
//upward communication
#include<stdio.h>
void upFun(int*,int*);
void main(void)
{
int a,b;
upFun(&a,&b);
printf("Value of a, b are:%d,%d",a,b);
}
Bi-directional communication occurs when the calling function sends data down to the called function.
After processing the called function sends data up to the calling.
The strategy described for upward communication can also be used for bi-direction communication, but
with a little modification.
The only change is that the indirect reference must be used in both sides of the assignment statement.
With this change the variable in the called function first is accessed for retrieving data using address
variable in the right hand side.
The same parameter is used again to store a value in the left-hand side.
Note: both upward and bidirectional communications are examples for pass by reference or call by
reference mechanisms.
//Bi-directional communication:
#include<stdio.h>
void biFun(int*,int*);
void main(void)
{
int a=2,b=3;
biFun(&a,&b);
printf("Value of a, b are:%d,%d",a,b);
}
void biFun(int* aptr,int* bptr)
{
*aptr = *aptr+24;
*bptr = *bptr+32;
}
Value of a,b are: 26, 35
C provides a rich collection of standard functions whose definitions have been written and are ready to be
used in our programs.
To use these functions, we must include their function declarations into our program.
The function declarations are generally found in header files.
Instead of adding each declaration separately, a simple statement with header file can be included on top of
the program.
Math functions
The real functions are fabs, fabsf and fabsl. For fabs the parameter is a double, and it returns a double. For
fabsf the parameter is a float and returns a float. For fabsl the parameter is a long double and returns a long
double.
General Syntax:
double fabs(double);
float fabsf(float);
long double fabsl(long double);
// Absolute value functions
#include<stdio.h>
#include<math.h>
void main(void)
{
float val=-2.674;
float res;
res = fabsf(val);
printf("Absolute value of %f is %f", val, res);
}
Output:
Absolute value of -2.674000 is 2.674000
Ceiling Functions
// Ceiling Functions
#include<stdio.h>
#include<math.h>
void main(void)
{
float val = 2.674;
float res;
res = ceilf(val);
printf("Ceiling value of %f is %f", val, res);
val = -2.674;
res = ceilf(val);
printf("\nCeiling value of %f is %f", val, res);
}
Output:
Ceiling value of 2.674000 is 3.000000
Ceiling value of -2.674000 is -2.000000
Floor Functions
A floor is the largest integral value that is equal to or less than a number.
Example: Floor of 3.99999 is 3.0.
On number series, this function moves the number left towards an integral value.
Truncate Functions
The truncate functions return the integral value in the direction of 0.
They are same as floor functions for positive numbers and same as ceiling function for negative numbers.
Their function declarations are:
double trunc (double);
float truncf (float);
long double truncl (long double);
Round Functions
The round functions return the nearest integral value.
Their function declarations are:
double round (double);
float roundf(float);
long double roundl(long double);
Power Functions:
The power (pow) function return the value of the x raised to the power of y.
An error occurs if the base (x) is negative and the exponent (y) is not an interger, or if the base is zero and
the exponent is not positive.
Individual data values of arrays can be passed using their index along with array name.
As long as the type is matching, the called function is unaware whether the value is coming from an array
or a normal variable.
Passing Addresses
The address of the elements of the array can also be passed to the function.
The individual element addresses can be passed just like any other variable address.
To pass an array element’s address, the address operator can be prefixed to the element’s indexed
reference.
Example: The address of 4th element in the array can be passed in following way: &arr[3];
Passing an address of an array element requires two changes in the called function.
Output:
Parameter received from calling function: 6
Array element after function call: 36
In C, the name of an array holds the address of the first element in the array.
Using array name and index values the complete array elements can be accessed.
Passing the array name instead of a single element, allows the called function to refer to the same array
back in the calling function.
//Passing whole array to called function
#include<stdio.h>
void arrAccess(int[]);
void main(void)
{
int a[5]={2,4,3,6,9},i;
arrAccess(a);
printf("\nAfter function call Elements in Array:");
for(i=0;i<5;i++)
printf("%d ", a[i]);
}