c _ Data Structures(Complete)
c _ Data Structures(Complete)
MCA SEMESTER –I
DATA STRUCTURES.
INDEX
UNIT I:
UNIT II:
UNIT III:
UNIT IV:
UNIT V:
DATA STRUCTURES
UNIT I:
Introduction to C:
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
#include<stdio.h>
return 0;
Constants:
KIET - MCA
DATA STRUCTURES
Numeric constant:
Real constant is also called floating point constant. To construct real constant we
must follow the rule of , -real constant must have at least one digit. -It must have a
decimal point. -It could be either positive or negative. -Default sign is positive. -No
commas or blanks are allowed within a real constant. Ex.: +325.34, 426.0, -32.76.
Character constant:
Character constant represented as a single character enclosed within a
single quote. These can be single digit, single special symbol or white spaces such
as ‘9’,’c’,’$’, ‘ ’ etc. Every character constant has a unique integer like value in
machine’s character code as if machine using ASCII (American standard code for
information interchange). Some numeric value associated with each upper and
lower case alphabets and decimal integers are as:
A------------ Z ASCII value (65-90)
a-------------z ASCII value (97-122)
0-------------9 ASCII value (48-59)
; ASCII value (59)
String constant
Set of characters are called string and when sequence of
characters are enclosed within a double quote (it may be combination of all kind of
symbols) is a string constant. String constant has zero, one or more than one
KIET - MCA
DATA STRUCTURES
character and at the end of the string null character(\0) is automatically placed by
compiler. Some examples are “,sarathina” , “908”, “3”,” ”, “A” etc. In C although
same characters are enclosed within single and double quotes it represents different
meaning such as “A” and ‘A’ are different because first one is string attached with
null character at the end but second one is character constant with its
corresponding ASCII value is 65.
Variables in ‘C’ :
Variable is a data name which is used to store some data value or
symbolic names for storing program computations and results. The value of the
variable can be change during the execution. The rule for naming the variables is
same as the naming identifier. Before used in the program it must be declared.
Declaration of variables specify its name, data types and range of the value that
variables can store depends upon its data types.
KIET - MCA
DATA STRUCTURES
C Operators
An operator is simply a symbol that is used to perform operations. There can be
many types of operations like arithmetic, logical, bitwise, etc.
There are following types of operators to perform different types of operations in C
language.
o Arithmetic Operators
o Relational Operators
o Shift Operators
o Logical Operators
KIET - MCA
DATA STRUCTURES
o Bitwise Operators
o Ternary or Conditional Operators
o Assignment Operator
o Misc Operator
Category Operator Associativity
Expressions :
An expression is a combination of variables, constants, operators and
function call. It can be arithmetic, logical and relational .
for example:-
int z= x+y //
arithmatic expression a>b //
relational a==b // logical func(a, b) //
function call Expressions consisting entirely of constant values are called constant
expressions.
KIET - MCA
DATA STRUCTURES
So, the expression 121 + 17 - 110 is a constant expression because each of the
terms of the expression is a constant value.
But if i were declared to be an integer variable, the expression 180 + 2 – j would
not represent a constant expression.
The getchar() and putchar() Functions
The int getchar(void) function reads the next available
character from the screen and returns it as an integer. This function reads only
single character at a time. You can use this method in the loop in case you want to
read more than one character from the screen.
The int putchar(int c) function puts the passed character
on the screen and returns the same character. This function puts only single
character at a time. You can use this method in the loop in case you want to display
more than one character on the screen.
The scanf() and printf() Functions
The int scanf(const char *format, ...) function reads the input
from the standard input stream stdin and scans that input according to
the format provided.
The int printf(const char *format, ...) function writes the output
to the standard output stream stdout and produces the output according to the
format provided.
The format can be a simple constant string, but you can specify %s, %d, %c, %f,
etc., to print or read strings, integer, character or float respectively. There are many
other formatting options available which can be used based on requirements.
KIET - MCA
DATA STRUCTURES
2 if...else statement
An if statement can be followed by an optional else
statement, which executes when the Boolean expression is
false.
3 nested if statements
You can use one if or else if statement inside another if or else
if statement(s).
4 switch statement
A switch statement allows a variable to be tested for equality
against a list of values.
5 nested switch statements
You can use one switch statement inside
another switch statement(s).
KIET - MCA
DATA STRUCTURES
ARRAY:
Array is the collection of similar data types or collection of similar
entity stored in contiguous memory location. Array of character is a string. Each
data item of an array is called an element. And each element is unique and located
in separated memory location. Each of elements of an array share a variable but
each element having different index no. known as subscript.
An array can be a single dimensional or multi-dimensional and
number of subscripts determines its dimension. And number of subscript is always
starts with zero. One dimensional array is known as vector and two dimensional
arrays are known as matrix.
ADVANTAGES: array variable can store more than one value at a time where
other variable can store one value at a time.
KIET - MCA
DATA STRUCTURES
Arrays in Detail
Arrays are important to C and should need a lot more attention.
The following important concepts related to array should be clear to a C
programmer −
Sr.No. Concept & Description
1 Multi-dimensional arrays
C supports multidimensional arrays. The simplest form of the
multidimensional array is the two-dimensional array.
2 Passing arrays to functions
You can pass to the function a pointer to an array by specifying
the array's name without an index.
3 Return array from a function
C allows a function to return an array.
4 Pointer to an array
You can generate a pointer to the first element of an array by
simply specifying the array name, without any index.
KIET - MCA
DATA STRUCTURES
UNIT II
Functions :
A function is a group of statements that together perform a task. Every C
program has at least one function, which is main(), and all the most trivial
programs can define additional functions.
A function declaration tells the compiler about a function's
name, return type, and parameters. A function definition provides the actual body
of the function.
The C standard library provides numerous built-in functions that
your program can call. For example, strcat() to concatenate two
strings, memcpy() to copy one memory location to another location, and many
more functions.
A function can also be referred as a method or a sub-routine or a
procedure, etc.
Defining a Function:
The general form of a function definition in C programming
language is as follows −
return_type function_name( parameter list ) {
body of the function
}
A function definition in C programming consists of a function header and
a function body. Here are all the parts of a function −
• Return Type − A function may return a value. The return_type is the data
type of the value the function returns. Some functions perform the desired
operations without returning a value. In this case, the return_type is the
keyword void.
• Function Name − This is the actual name of the function. The function
name and the parameter list together constitute the function signature.
• Parameters − A parameter is like a placeholder. When a function is
invoked, you pass a value to the parameter. This value is referred to as actual
parameter or argument. The parameter list refers to the type, order, and
number of the parameters of a function. Parameters are optional; that is, a
function may contain no parameters.
• Function Body − The function body contains a collection of statements that
define what the function does.
KIET - MCA
DATA STRUCTURES
Function Declarations:
• A function declaration tells the compiler about a function name and how to
call the function. The actual body of the function can be defined separately.
• A function declaration has the following parts −
• return_type function_name( parameter list );
• For the above defined function max(), the function declaration is as follows
−
• int max(int num1, int num2);
• Parameter names are not important in function declaration only their type is
required, so the following is also a valid declaration −
• int max(int, int);
• Function declaration is required when you define a function in one source
file and you call that function in another file. In such case, you should
declare the function at the top of the file calling the function.
Calling a Function:
While creating a C function, you give a definition of what the function has
to do. To use a function, you will have to call that function to perform the defined
task.
When a program calls a function, the program control is transferred to the
called function. A called function performs a defined task and when its return
statement is executed or when its function-ending closing brace is reached, it
returns the program control back to the main program.
To call a function, you simply need to pass the required parameters along
with the function name, and if the function returns a value, then you can store the
returned value.
Function Arguments:
If a function is to use arguments, it must declare variables that accept the values of
the arguments. These variables are called the formal parameters of the function.
Formal parameters behave like other local variables inside the function and are
created upon entry into the function and destroyed upon exit.
While calling a function, there are two ways in which arguments can be passed to
a function –
KIET - MCA
DATA STRUCTURES
1 Call by value
This method copies the actual value of an argument into the
formal parameter of the function. In this case, changes made
to the parameter inside the function have no effect on the
argument.
2 Call by reference
This method copies the address of an argument into the
formal parameter. Inside the function, the address is used to
access the actual argument used in the call. This means that
changes made to the parameter affect the argument.
By default, C uses call by value to pass arguments. In general, it means the code
within a function cannot alter the arguments used to call the function.
Structure:
Arrays allow to define type of variables that can hold several data items
of the same kind. Similarly structure is another user defined data type available in
C that allows to combine data items of different kinds.
Structures are used to represent a record. Suppose you want to keep track of your
books in a library. You might want to track the following attributes about each
book −
• Title
• Author
• Subject
• Book ID
Defining a Structure:
To define a structure, you must use the struct statement. The struct statement
defines a new data type, with more than one member. The format of the struct
statement is as follows −
struct [structure tag] {
KIET - MCA
DATA STRUCTURES
member definition;
member definition;
...
member definition;
} [one or more structure variables];
The structure tag is optional and each member definition is a normal variable
definition, such as int i; or float f; or any other valid variable definition. At the end
of the structure's definition, before the final semicolon, you can specify one or
more structure variables but it is optional. Here is the way you would declare the
Book structure −
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
Union:
A union is a special data type available in C that allows to store different
data types in the same memory location. You can define a union with many
members, but only one member can contain a value at any given time. Unions
provide an efficient way of using the same memory location for multiple-purpose.
Defining a Union
To define a union, you must use the union statement in the same way as you did
while defining a structure. The union statement defines a new data type with more
than one member for your program. The format of the union statement is as
follows −
union [union tag] {
member definition;
member definition;
KIET - MCA
DATA STRUCTURES
...
member definition;
} [one or more union variables];
The union tag is optional and each member definition is a normal
variable definition, such as int i; or float f; or any other valid variable definition.
At the end of the union's definition, before the final semicolon, you can specify
one or more union variables but it is optional. Here is the way you would define a
union type named Data having three members i, f, and str −
union Data {
int i;
float f;
char str[20];
} data;
Now, a variable of Data type can store an integer, a floating-point
number, or a string of characters. It means a single variable, i.e., same memory
location, can be used to store multiple types of data. You can use any built-in or
user defined data types inside a union based on your requirement.
Let's see a simple example of union in C language.
1. #include <stdio.h>
2. #include <string.h>
3. union employee
4. { int id;
5. char name[50];
6. }e1; //declaring e1 variable for union
7. int main( )
8. {
9. //store first employee information
10. e1.id=101;
11. strcpy(e1.name, "Sonoo Jaiswal");//copying string into char array
12. //printing first employee information
KIET - MCA
DATA STRUCTURES
int main () {
int var1;
char var2[10];
return 0;
}
KIET - MCA
DATA STRUCTURES
When the above code is compiled and executed, it produces the following result −
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
What are Pointers?
A pointer is a variable whose value is the address of another variable, i.e., direct
address of the memory location. Like any variable or constant, you must declare a
pointer before using it to store any variable address. The general form of a pointer
variable declaration is −
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-
name is the name of the pointer variable. The asterisk * used to declare a pointer
is the same asterisk used for multiplication. However, in this statement the
asterisk is being used to designate a variable as a pointer. Take a look at some of
the valid pointer declarations −
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
The actual data type of the value of all pointers, whether integer,
float, character, or otherwise, is the same, a long hexadecimal number that
represents a memory address. The only difference between pointers of different
data types is the data type of the variable or constant that the pointer points to.
How to Use Pointers?
There are a few important operations, which we will do with the help of pointers
very frequently. (a) We define a pointer variable, (b) assign the address of a
variable to a pointer and (c) finally access the value at the address available in the
pointer variable. This is done by using unary operator * that returns the value of
the variable located at the address specified by its operand. The following
example makes use of these operations −
#include <stdio.h>
int main () {
KIET - MCA
DATA STRUCTURES
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
NULL Pointers
It is always a good practice to assign a NULL value to a pointer variable in case
you do not have an exact address to be assigned. This is done at the time of
variable declaration. A pointer that is assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in several standard
libraries. Consider the following program −
#include <stdio.h>
KIET - MCA
DATA STRUCTURES
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
The value of ptr is 0
In most of the operating systems, programs are not permitted to access memory at
address 0 because that memory is reserved by the operating system. However, the
memory address 0 has special significance; it signals that the pointer is not
intended to point to an accessible memory location. But by convention, if a
pointer contains the null (zero) value, it is assumed to point to nothing.
To check for a null pointer, you can use an 'if' statement as follows −
if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
Pointers in Detail
Pointers have many but easy concepts and they are very important to C
programming. The following important pointer concepts should be clear to any C
programmer −
1 Pointer arithmetic
There are four arithmetic operators that can be used in
pointers: ++, --, +, -
KIET - MCA
DATA STRUCTURES
2 Array of pointers
You can define arrays to hold a number of pointers.
3 Pointer to pointer
C allows you to have pointer on a pointer and so on.
File Handling in C
In programming, we may require some specific
input data to be generated several numbers of times. Sometimes, it is not enough
to only display the data on the console. The data to be displayed may be very
large, and only a limited amount of data can be displayed on the console, and
since the memory is volatile, it is impossible to recover the programmatically
generated data again and again. However, if we need to do so, we may store it
onto the local file system which is volatile and can be accessed every time. Here,
comes the need of file handling in C.
File handling in C enables us to create, update, read, and delete the
files stored on the local file system through our C program. The following
operations can be performed on a file.
o Creation of the new file
o Opening an existing file
o Reading from the file
o Writing to the file
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
UNIT – 3
Data structure: Definition, types of data structures Recursion Definition, Design
Methodology and Implementation of recursive algorithms, Linear and binary
recursion. Preliminaries of algorithms, analysis and complexity .
Linear list – singly linked list, Double linked list and circular linked list -
implementation, insertion, deletion and searching operations on linear list.
----------------------------------------------------------------------------------------------------
KIET - MCA
DATA STRUCTURES
Queues
Stacks
Linked lists
Tree: In this case, data often contain a hierarchical relationship among various
elements. The data structure that reflects this relationship is termed as rooted tree
graph or a tree.
Graph: In this case, data sometimes hold a relationship between the pairs of
elements which is not necessarily following the hierarchical structure. Such data
structure is termed as a Graph.
Array is a container which can hold a fix number of items and these items should
be of the same type. Most of the data structures make use of arrays to implement
their algorithms. Following are the important terms to understand the concept of
Array.
Element − Each item stored in an array is called an element.
Index − Each location of an element in an array has a numerical index, which is
used to identify the element
Recursion:
Recursion is the process of repeating items in a self-similar way. In
programming languages, if a program allows you to call a function inside the same
function, then it is called a recursive call of the function.
void recursion() {
recursion(); /* function calls itself */
}
int main() {
recursion();
}
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
This activation record keeps the information about local variables, formal
parameters, return address and all information passed to the caller function.
Analysis of Recursion
One may argue why to use recursion, as the same task can be
done with iteration. The first reason is, recursion makes a program more readable
and because of latest enhanced CPU systems, recursion is more efficient than
iterations.
Time Complexity
In case of iterations, we take number of iterations to count the
time complexity. Likewise, in case of recursion, assuming everything is constant,
we try to figure out the number of times a recursive call is being made. A call
made to a function is Ο(1), hence the (n) number of times a recursive call is made
makes the recursive function Ο(n).
Space Complexity
Space complexity is counted as what amount of extra space is
required for a module to execute. In case of iterations, the compiler hardly requires
any extra space. The compiler keeps updating the values of variables used in the
iterations. But in case of recursion, the system needs to store activation record each
time a recursive call is made. Hence, it is considered that space complexity of
recursive function may go higher than that of a function with iteration.
KIET - MCA
DATA STRUCTURES
i. Perform a single recursive call. In this process the recursive step involves a
test which decide out of all the several possible recursive calls which one is
make, but it should ultimately choose to make just one of these calls each
time we perform this step.
ii. Define each possible recursive call, so that it makes progress towards a base
case.
A simple example of linear recursion.
Input
An integer array A and an integer n=1, such that A has at least n elements.
Output
The sum of first n integer in A
If n=1 then
return A[0]
else
return LinearSum (A, n-1) + A[n-1]
In creating recursive methods, it is important to define the methods in a way that
facilitate recursion. This sometimes requires we define additional parameters that
are passed to the method. For example, we define the array reversal method
as ReverseArray (A, i, j), not ReverseArray (A).
Algorithm
ReverseArray (A, i, j);
Input
An array A and non-negative integer indices i and j.
Output
The revesal of the elements in A starting at index I and ending at index j.
If i<j then
Swap A[i] and A[j]
ReverseArray (A, i+1, j-1)
return
2. Binary recursion
Binary recursion occurs whenever there are two recursive calls for each non base
case. Example is the problem to add all the numbers in an integer array A.
Algorithm
BinarySum (A, i, n)
Input
An array A and integers i and n.
Output
The sum of the integers in A starting from index i,
If n=1 then
return A[i]
KIET - MCA
DATA STRUCTURES
else
return BinarySum [A, i, n/2] + BinarySum [A, i+n/2, n/2]
Example trace
Another example of binary recursion is computing Fibonacci numbers, Fibonacci
numbers are defined recursively:
F0 = 0
F1 = 0
Fi = Fi-1 + Fi-2 for i>1
If K=1
Then return K
Else
return BinaryFib (K-1) + BinaryFib (K-2)
n0 = 1
n1 = 1
n2 = n1 + n0 + 1 = 1 + 1 + 1 = 3
n3 = n1 + n2 + 1 = 3 + 1 + 1 = 5
n4 = n3 + n2 + 1 = 5 + 3 + 1 = 9
n5 = n4 + n3 + 1 = 9 + 5 + 1 = 15
n6 = n5 + n4 + 1 = 15 + 9 + 1 = 25
n7 = n6 + n5 + 1 = 25 + 15 + 1 = 41
n8 = n7 + n6 + 1 = 41 + 25 + 1 = 67
Note that the value at least doubles for every other value of nk. That is nk > 2k/2. It
is exponential.
We can write the better Fibonacci algorithm which can run in O(k) time using
linear recursion rather than binary recursion.
KIET - MCA
DATA STRUCTURES
3. Multiple Recursion
In multiple recursion we make not just one or two calls but many
recursive calls. One of the motivating examples is summation puzzles.
Algorithm Analysis
Analysis of efficiency of an algorithm can be performed at
two different stages, before implementation and after implementation, as
A priori analysis − This is defined as theoretical analysis of an algorithm.
Efficiency of algorithm is measured by assuming that all other
factors e.g. speed of processor, are constant and have no effect on implementation.
A posterior analysis − This is defined as empirical analysis of an algorithm. The
chosen algorithm is implemented using programming language. Next the chosen
KIET - MCA
DATA STRUCTURES
Algorithm Complexity
KIET - MCA
DATA STRUCTURES
Time Complexity
LINKED LIST :
A linked list is a sequence of data structures, which are connected
together via links. Linked List is a sequence of links which contains items. Each
link contains a connection to another link. Linked list is the second most-used data
structure after array.
Following are the important terms to understand the concept of Linked List.
Link − Each link of a linked list can store a data called an element.
Next − Each link of a linked list contains a link to the next link called Next.
LinkedList − A Linked List contains the connection link to the first link called
First.
Linked List Representation
Linked list can be visualized as a chain of nodes, where every node points to the
next node.
As per the above illustration, following are the important points to be considered.
Linked List contains a link element called first.
Each link carries a data field(s) and a link field called next.
Each link is linked with its next link using its next link.
Last link carries a link as null to mark the end of the list.
KIET - MCA
DATA STRUCTURES
Circular Linked List − Last item contains link of the first element as next and
the first element has a link to the last element as previous.
Basic Operations
Following are the basic operations supported by a list.
Insertion − Adds an element at the beginning of the list.
Deletion − Deletes an element at the beginning of the list.
Display − Displays the complete list.
Search − Searches an element using the given key.
Delete − Deletes an element using the given key.
Insertion Operation
Adding a new node in linked list is a more than one step activity. We shall learn
this with diagrams here. First, create a node using the same structure and find the
location where it has to be inserted.
Now, the next node at the left should point to the new node.
LeftNode.next −> NewNode;
KIET - MCA
DATA STRUCTURES
This will put the new node in the middle of the two. The new list should look like
this –
Similar steps should be taken if the node is being inserted at the beginning of the
list. While inserting it at the end, the second last node of the list should point to the
new node and the new node will point to NULL
Deletion Operation
Deletion is also a more than one step process. We shall learn with pictorial
representation. First, locate the target node to be removed, by using searching
algorithms.
The left (previous) node of the target node now should point to the next node of the
target node −
LeftNode.next −> TargetNode.next;
This will remove the link that was pointing to the target node. Now, using the
following code, we will remove what the target node is pointing at.
TargetNode.next −> NULL;
KIET - MCA
DATA STRUCTURES
We need to use the deleted node. We can keep that in memory otherwise we can
simply deallocate memory and wipe off the target node completely.
Reverse Operation
This operation is a thorough one. We need to make the last node to be pointed by
the head node and reverse the whole linked list.
First, we traverse to the end of the list. It should be pointing to NULL. Now, we
shall make it point to its previous node –
We have to make sure that the last node is not the lost node. So we'll have some
temp node, which looks like the head node pointing to the last node. Now, we shall
make all left side nodes point to their previous nodes one by one.
Except the node (first node) pointed by the head node, all nodes should point to
their predecessor, making them their new successor. The first node will point to
NULL.
KIET - MCA
DATA STRUCTURES
We'll make the head node point to the new first node by using the temp node
In the above figure, the arrow represents the links. The data part of every node
contains the marks obtained by the student in the different subject. The last node in
the list is identified by the null pointer which is present in the address part of the
last node. We can have as many elements we require, in the data part of the list.
KIET - MCA
DATA STRUCTURES
1 Insertion at It involves inserting any element at the front of the list. We just
beginning need to a few link adjustments to make the new node as the head
of the list.
2 Insertion at end It involves insertion at the last of the linked list. The new node can
of the list be inserted as the only node in the list or it can be inserted as the
last one. Different logics are implemented in each scenario.
3 Insertion after It involves insertion after the specified node of the linked list. We
specified node need to skip the desired number of nodes in order to reach the node
after which the new node will be inserted. .
KIET - MCA
SN Operation Description DATA STRUCTURES
1 Deletion at It involves deletion of a node from the beginning of the list. This is the
beginning simplest operation among all. It just need a few adjustments in the node
pointers.
2 Deletion at the It involves deleting the last node of the list. The list can either be empty
end of the list or full. Different logic is implemented for the different scenarios.
3 Deletion after It involves deleting the node after the specified node in the list. we need
specified node to skip the desired number of nodes to reach the node after which the
node will be deleted. This requires traversing through the list.
4 Traversing In traversing, we simply visit each node of the list at least once in order
to perform some specific operation on it, for example, printing data part
of each node present in the list.
5 Searching In searching, we match each element of the list with the given element. If
the element is found on any of the location then location of that element
is returned otherwise null is returned. .
Deletion and Traversing
The Deletion of a node from a singly linked list can be performed
at different positions. Based on the position of the node being deleted, the
operation is categorized into the following categories.
KIET - MCA
DATA STRUCTURES
A doubly linked list containing three nodes having numbers from 1 to 3 in their
data part, is shown in the following image.
KIET - MCA
DATA STRUCTURES
The prev part of the first node and the next part of the last node will always
contain null indicating end in each direction.
In a singly linked list, we could traverse only in one direction,
because each node contains address of the next node and it doesn't have any record
of its previous nodes. However, doubly linked list overcome this limitation of
singly linked list. Due to the fact that, each node of the list contains the address of
its previous node, we can find all the details about the previous node as well by
using the previous address stored inside the previous part of each node.
KIET - MCA
DATA STRUCTURES
In a circular Singly linked list, the last node of the list contains a pointer
to the first node of the list. We can have circular singly linked list as well as
circular doubly linked list.
We traverse a circular singly linked list until we reach the same node
where we started. The circular singly liked list has no beginning and no ending.
There is no null value present in the next part of any of the nodes.
The following image shows a circular singly linked list.
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
We can also have more than one number of linked list in the
memory with the different start pointers pointing to the different start nodes in the
list. The last node is identified by its next part which contains the address of the
start node of the list. We must be able to identify the last node of any linked list so
that we can find out the number of iterations which need to be performed while
traversing the list.
KIET - MCA
DATA STRUCTURES
UNIT-4
What is a Stack?
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
POP operation
o Before deleting the element from the stack, we check whether the stack is
empty.
o If we try to delete the element from the empty stack, then
the underflow condition occurs.
o If the stack is not empty, we first access the element which is pointed by
the top
o Once the pop operation is performed, the top is decremented by 1,
i.e., top=top-1.
Applications of Stack
The following are the applications of the stack:
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
o Prefix to infix
o Prefix to postfix
Postfix to infix
o Memory management: The stack manages the memory. The memory is
assigned in the contiguous memory blocks. The memory is known as stack
memory as all the variables are assigned in a function call stack memory.
The memory size assigned to the program is known to the compiler. When
the function is created, all its variables are assigned in the stack memory.
When the function completed its execution, all the variables assigned in the
stack are released.
Array implementation of Stack
In array implementation, the stack is formed by using
the array. All the operations regarding the stack are performed using arrays. Lets
see how each operation can be implemented on the stack using array data structure.
Adding an element onto the stack (push operation)
Adding an element into the top of the stack is referred to as push operation. Push
operation involves following two steps.
1. Increment the variable Top so that it can now refere to the next memory
location.
2. Add element at the position of incremented top. This is referred to as adding
new element at the top of the stack.
Stack is overflown when we try to insert an element into a completely filled stack
therefore, our main function must always avoid stack overflow condition.
Algorithm:
1. begin
2. if top = n then stack full
3. top = top + 1
4. stack (top) : = item;
5. end
Time Complexity : o(1)
implementation of push algorithm in C language
1. void push (int val,int n) //n is size of the stack
2. {
3. if (top == n )
4. printf("\n Overflow");
5. else
6. {
7. top = top +1;
8. stack[top] = val;
9. }
KIET - MCA
DATA STRUCTURES
10.}
Deletion of an element from a stack (Pop operation)
Deletion of an element from the top of the stack is called pop operation. The value
of the variable top will be incremented by 1 whenever an item is deleted from the
stack. The top most element of the stack is stored in an another variable and then
the top is decremented by 1. the operation returns the deleted value that was stored
in another variable as the result.
The underflow condition occurs when we try to delete an element from an already
empty stack.
Algorithm :
1. begin
2. if top = 0 then stack empty;
3. item := stack(top);
4. top = top - 1;
5. end;
Time Complexity : o(1)
KIET - MCA
DATA STRUCTURES
5. End
Time complexity: o(n)
The top most node in the stack always contains null in its address field.
Lets discuss the way in which, each operation is performed in linked list
implementation of stack.
Adding a node to the stack (Push operation)
Adding a node to the stack is referred to as push operation. Pushing an element to
a stack in linked list implementation is different from that of an array
implementation. In order to push an element onto the stack, the following steps are
involved.
1. Create a node first and allocate memory to it.
2. If the list is empty then the item is to be pushed as the start node of the list.
This includes assigning value to the data part of the node and assign null to
the address part of the node.
KIET - MCA
DATA STRUCTURES
3. If there are some nodes in the list already, then we have to add the new
element in the beginning of the list (to not violate the property of the stack).
For this purpose, assign the address of the starting element to the address
field of the new node and make the new node, the starting node of the list.
Time Complexity : o(1)
KIET - MCA
DATA STRUCTURES
Queue:
Applications of Queue
Due to the fact that queue performs actions on first in first out basis which is quite
fair for the ordering of actions. There are various applications of queues discussed
as below.
1. Queues are widely used as waiting lists for a single shared resource like
printer, disk, CPU.
2. Queues are used in asynchronous transfer of data (where data is not being
transferred at the same rate between two processes) for eg. pipes, file IO,
sockets.
3. Queues are used as buffers in most of the applications like MP3 media
player, CD player, etc.
KIET - MCA
DATA STRUCTURES
4. Queue are used to maintain the play list in media players in order to add and
remove the songs from the play-list.
5. Queues are used in operating systems for handling interrupts.
Operations on Queue
KIET - MCA
DATA STRUCTURES
Types of Queue
o Linear Queue
In Linear Queue, an insertion takes place from one end
while the deletion occurs from another end. The end at which the insertion takes
place is known as the rear end, and the end at which the deletion takes place is
known as front end. It strictly follows the FIFO rule. The linear Queue can be
represented, as shown in the below figure:
The above figure shows that the elements are inserted from the
rear end, and if we insert more elements in a Queue, then the rear value gets
incremented on every insertion. If we want to show the deletion, then it can be
represented as:
o Circular Queue
In Circular Queue, all the nodes are represented as
circular. It is similar to the linear Queue except that the last element of the queue is
KIET - MCA
DATA STRUCTURES
connected to the first element. It is also known as Ring Buffer as all the ends are
connected to another end. The circular queue can be represented as:
o Deque
Both the Linear Queue and Deque are different as the linear queue follows the
FIFO principle whereas, deque does not follow the FIFO principle. In Deque, the
insertion and deletion can occur from both ends.
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
Algorithm
o Step 1: IF REAR = MAX - 1
Write OVERFLOW
Go to step
[END OF IF]
o Step 2: IF FRONT = -1 and REAR = -1
SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1
[END OF IF]
o Step 3: Set QUEUE[REAR] = NUM
o Step 4: EXIT
Algorithm
KIET - MCA
DATA STRUCTURES
In the linked queue, there are two pointers maintained in the memory
i.e. front pointer and rear pointer. The front pointer contains the address of the
starting element of the queue while the rear pointer contains the address of the last
element of the queue.
Insertion and deletions are performed at rear and front end
respectively. If front and rear both are NULL, it indicates that the queue is empty.
Insert operation
The insert operation append the queue by adding an element to
the end of the queue. The new element will be the last element of the queue.
Firstly, allocate the memory for the new node ptr by using the following statement.
1. Ptr = (struct node *) malloc (sizeof(struct node));
There can be the two scenario of inserting this new node ptr into the linked queue.
KIET - MCA
DATA STRUCTURES
Algorithm
KIET - MCA
DATA STRUCTURES
Deletion:
Algorithm
KIET - MCA
DATA STRUCTURES
Hashing
• (1,20)
• (2,70)
• (42,80)
• (4,25)
• (12,44)
• (14,32)
• (17,11)
• (13,78)
• (37,98)
Linear Probing
KIET - MCA
DATA STRUCTURES
Basic Operations
Following are the basic primary operations of a hash table.
• Search − Searches an element in a hash table.
• Insert − inserts an element in a hash table.
• delete − Deletes an element from a hash table.
DataItem
Define a data item having some data and key, based on which the search is to be
conducted in a hash table.
struct DataItem {
int data;
int key;
};
Hash Method
Define a hashing method to compute the hash code of the key of the data item.
int hashCode(int key){
return key % SIZE;
}
Search Operation
Insert Operation
KIET - MCA
DATA STRUCTURES
KIET - MCA
DATA STRUCTURES
inserted in slot at the hashed index else it proceeds in some probe sequence until it
finds an unoccupied slot.
The probe sequence is the sequence that is followed while
traversing through entries. In different probe sequences, you can have different
intervals between successive entry slots or probes.
KIET - MCA
DATA STRUCTURES
Quadratic Probing
Double hashing
Rehashing:
KIET - MCA
DATA STRUCTURES
Why rehashing?
Extendible Hashing
It is a dynamic hashing method wherein directories, and buckets
are used to hash data. It is an aggressively flexible method in which the hash
function also experiences dynamic changes.
Main features of Extendible Hashing: The main features in this hashing
technique are:
• Directories: The directories store addresses of the buckets in pointers. An id
is assigned to each directory which may change each time when Directory
Expansion takes place.
• Buckets: The buckets are used to hash the actual data.
KIET - MCA
DATA STRUCTURES
Advantages:
1. Data retrieval is less expensive (in terms of computing).
2. No problem of Data-loss since the storage capacity increases dynamically.
3. With dynamic changes in hashing function, associated old values are
rehashed w.r.t the new hash function.
KIET - MCA
DATA STRUCTURES
4.
Limitations Of Extendible Hashing:
1. The directory size may increase significantly if several records are hashed on
the same directory while keeping the record distribution non-uniform.
2. Size of every bucket is fixed.
3. Memory is wasted in pointers when the global depth and local depth
difference becomes drastic.
Applications
KIET - MCA
DATA STRUCTURES
UNIT – 5
Sorting:
Sorting refers to arranging data in a particular format. Sorting
algorithm specifies the way to arrange data in a particular order. Most common
orders are in numerical or lexicographical order.
The importance of sorting lies in the fact that data searching can be optimized to a
very high level, if data is stored in a sorted manner. Sorting is also used to
represent data in more readable formats. Following are some of the examples of
sorting in real-life scenarios −
• Telephone Directory − The telephone directory stores the telephone
numbers of people sorted by their names, so that the names can be searched
easily.
• Dictionary − The dictionary stores words in an alphabetical order so that
searching of any word becomes easy.
Insertion sort:
This is an in-place comparison-based sorting algorithm. Here, a
sub-list is maintained which is always sorted. For example, the lower part of an
array is maintained to be sorted. An element which is to be 'insert'ed in this sorted
sub-list, has to find its appropriate place and then it has to be inserted there. Hence
the name, insertion sort.
The array is searched sequentially and unsorted items are moved and
inserted into the sorted sub-list (in the same array). This algorithm is not suitable
for large data sets as its average and worst case complexity are of Ο(n2), where n is
the number of items.
KIET - MCA
DATA STRUCTURES
It finds that both 14 and 33 are already in ascending order. For now, 14 is in sorted
sub-list.
It swaps 33 with 27. It also checks with all the elements of sorted sub-list. Here we
see that the sorted sub-list has only one element 14, and 27 is greater than 14.
Hence, the sorted sub-list remains sorted after swapping.
By now we have 14 and 27 in the sorted sub-list. Next, it compares 33 with 10.
So we swap them.
KIET - MCA
DATA STRUCTURES
We swap them again. By the end of third iteration, we have a sorted sub-list of 4
items.
This process goes on until all the unsorted values are covered in a sorted sub-list.
Now we shall see some programming aspects of insertion sort.
Algorithm
Now we have a bigger picture of how this sorting technique works, so we can
derive simple steps by which we can achieve insertion sort.
Selection sort:
The smallest element is selected from the unsorted array and swapped
with the leftmost element, and that element becomes a part of the sorted array. This
process continues moving unsorted array boundary by one element to the right.
This algorithm is not suitable for large data sets as its average and worst case
complexities are of Ο(n2), where n is the number of items.
KIET - MCA
DATA STRUCTURES
For the first position in the sorted list, the whole list is scanned sequentially. The
first position where 14 is stored presently, we search the whole list and find that 10
is the lowest value.
So we replace 14 with 10. After one iteration 10, which happens to be the
minimum value in the list, appears in the first position of the sorted list.
For the second position, where 33 is residing, we start scanning the rest of the list
in a linear manner.
We find that 14 is the second lowest value in the list and it should appear at the
second place. We swap these values.
After two iterations, two least values are positioned at the beginning in a sorted
manner.
The same process is applied to the rest of the items in the array.
Following is a pictorial depiction of the entire sorting process −
KIET - MCA
DATA STRUCTURES
Algorithm
Step 1 − Set MIN to location 0
Step 2 − Search the minimum element in the list
Step 3 − Swap with value at location MIN
Step 4 − Increment MIN to point to next element
Step 5 − Repeat until list is sorted
KIET - MCA
DATA STRUCTURES
Bubble sort:
Bubble sort is a simple sorting algorithm. This sorting algorithm
is comparison-based algorithm in which each pair of adjacent elements is
compared and the elements are swapped if they are not in order. This algorithm is
not suitable for large data sets as its average and worst case complexity are of
Ο(n2) where n is the number of items.
We take an unsorted array for our example. Bubble sort takes Ο(n2) time
so we're keeping it short and precise.
Bubble sort starts with very first two elements, comparing them to check which
one is greater.
In this case, value 33 is greater than 14, so it is already in sorted locations. Next,
we compare 33 with 27.
We find that 27 is smaller than 33 and these two values must be swapped.
Next we compare 33 and 35. We find that both are in already sorted positions.
We know then that 10 is smaller 35. Hence they are not sorted.
KIET - MCA
DATA STRUCTURES
We swap these values. We find that we have reached the end of the array. After
one iteration, the array should look like this −
To be precise, we are now showing how an array should look like after each
iteration. After the second iteration, it should look like this −
Notice that after each iteration, at least one value moves at the end.
And when there's no swap required, bubble sorts learns that an array is completely
sorted.
Algorithm
return list
end BubbleSort
KIET - MCA
DATA STRUCTURES
Merge sort
Merge sort is a sorting technique based on divide and conquer technique. With
worst-case time complexity being Ο(n log n), it is one of the most respected
algorithms.
Merge sort first divides the array into equal halves and then combines them in a
sorted manner.
We know that merge sort first divides the whole array iteratively into equal halves
unless the atomic values are achieved. We see here that an array of 8 items is
divided into two arrays of size 4.
This does not change the sequence of appearance of items in the original. Now we
divide these two arrays into halves.
We further divide these arrays and we achieve atomic value which can no more be
divided.
Now, we combine them in exactly the same manner as they were broken down.
Please note the color codes given to these lists.
We first compare the element for each list and then combine them into another list
in a sorted manner. We see that 14 and 33 are in sorted positions. We compare 27
and 10 and in the target list of 2 values we put 10 first, followed by 27. We change
the order of 19 and 35 whereas 42 and 44 are placed sequentially.
In the next iteration of the combining phase, we compare lists of two data values,
and merge them into a list of found data values placing all in a sorted order.
KIET - MCA
DATA STRUCTURES
After the final merging, the list should look like this −
Algorithm
Merge sort keeps on dividing the list into equal halves until it can
no more be divided. By definition, if it is only one element in the list, it is sorted.
Then, merge sort combines the smaller sorted lists keeping the new list sorted too.
Step 1 − if it is only one element in the list it is already sorted, return.
Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order
Quick Sort
There are different versions of quick sort which choose the pivot in different ways:
KIET - MCA
DATA STRUCTURES
4. Median as pivot
Step 2: Take two variables to point left and right of the list excluding pivot.
Step 5: While value at left < (Less than) pivot move right.
Step 6: While value at right > (Greater than) pivot move left.
Step 7: If both Step 5 and Step 6 does not match, swap left and right.
Step 8: If left = (Less than or Equal to) right, the point where they met is new
pivot.
KIET - MCA
DATA STRUCTURES
The above diagram represents how to find the pivot value in an array. As we see,
pivot value divides the list into two parts (partitions) and then each part is
processed for quick sort. Quick sort is a recursive function. We can call the
partition function again.
KIET - MCA
DATA STRUCTURES
Trees:
Tree represents the nodes connected by edges. We will discuss binary tree
or binary search tree specifically.
Binary Tree is a special datastructure used for data storage purposes. A binary tree
has a special condition that each node can have a maximum of two children. A
binary tree has the benefits of both an ordered array and a linked list as search is as
quick as in a sorted array and insertion or deletion operation are as fast as in linked
list.
Important Terms
KIET - MCA
DATA STRUCTURES
Tree Traversal:
Traversal is a process to visit all the nodes of a tree and may print their
values too. Because, all nodes are connected via edges (links) we always start from
the root (head) node. That is, we cannot randomly access a node in a tree. There
are three ways which we use to traverse a tree −
• In-order Traversal
• Pre-order Traversal
• Post-order Traversal
Generally, we traverse a tree to search or locate a given item or key in the tree or to
print all the values it contains.
In-order Traversal
In this traversal method, the left subtree is visited first, then the root and
later the right sub-tree. We should always remember that every node may represent
a subtree itself.
If a binary tree is traversed in-order, the output will produce sorted key
values in an ascending order.
KIET - MCA
DATA STRUCTURES
D→B→E→A→F→C→G
Algorithm
Pre-order Traversal
In this traversal method, the root node is visited first, then the left subtree and
finally the right subtree.
KIET - MCA
DATA STRUCTURES
We start from A, and following pre-order traversal, we first visit A itself and then
move to its left subtree B. B is also traversed pre-order. The process goes on until
all the nodes are visited. The output of pre-order traversal of this tree will be −
A→B→D→E→C→F→G
Algorithm
Post-order Traversal
In this traversal method, the root node is visited last, hence the name. First we
traverse the left subtree, then the right subtree and finally the root node.
KIET - MCA
DATA STRUCTURES
We start from A, and following Post-order traversal, we first visit the left
subtree B. B is also traversed post-order. The process goes on until all the nodes
are visited. The output of post-order traversal of this tree will be −
D→E→B→F→G→C→A
Algorithm
KIET - MCA
DATA STRUCTURES
We're going to implement tree using node object and connecting them through
references.
Tree Node
The code to write a tree node would be similar to what is given below. It has a data
part and references to its left and right child nodes.
struct node {
int data;
struct node *leftChild;
struct node *rightChild;
};
In a tree, all nodes share common construct.
The basic operations that can be performed on a binary search tree data structure,
are the following −
• Insert − Inserts an element in a tree/create a tree.
• Search − Searches an element in a tree.
• Preorder Traversal − Traverses a tree in a pre-order manner.
• Inorder Traversal − Traverses a tree in an in-order manner.
• Postorder Traversal − Traverses a tree in a post-order manner.
Insert Operation
The very first insertion creates the tree. Afterwards, whenever an element is to be
inserted, first locate its proper location. Start searching from the root node, then if
the data is less than the key value, search for the empty location in the left subtree
and insert the data. Otherwise, search for the empty location in the right subtree
and insert the data.
KIET - MCA
DATA STRUCTURES
Algorithm
If root is NULL
then create root node
return
endwhile
insert data
end If
Search Operation
Whenever an element is to be searched, start searching from the root node, then
if the data is less than the key value, search for the element in the left subtree.
Otherwise, search for the element in the right subtree. Follow the same algorithm
for each node.
Algorithm
KIET - MCA
DATA STRUCTURES
If data found
return node
endwhile
end if
Deletion
The node to be deleted is a leaf node.It is the simplest case, in this case, replace the
leaf node with the NULL and simple free the allocated space.
In the following image, we are deleting the node 85, since the node is a leaf
node, therefore the node will be replaced with NULL and allocated space will be
freed.
In this case, replace the node with its child and delete the child node, which now
contains the value which is to be deleted. Simply replace it with the NULL and
free the allocated space.
KIET - MCA
DATA STRUCTURES
In the following image, the node 12 is to be deleted. It has only one child. The
node will be replaced with its child node and the replaced node 12 (which is now
leaf node) will simply be deleted.
In the following image, the node 50 is to be deleted which is the root node
of the tree. The in-order traversal of the tree given below.
replace 50 with its in-order successor 52. Now, 50 will be moved to the leaf of the
tree, which will simply be deleted.
KIET - MCA
DATA STRUCTURES
Algorithm
o Step 2: END
KIET - MCA