DSA Unit-1
DSA Unit-1
1. Introduction: Programming in C
• To learn about the structure of C program
• To learn about the primitive data types
• Understanding the Structure of a C Program
• Familiarity with Primitive Data Types
Structure of a C program
Comments:
• The comment lines are simply ignored by the compiler, that means they are not
executed. In C, there are two types of comments.
1. Single Line Comments: Single line comment begins with // symbol. We can write any
number of single line comments.
2. Multiple Lines Comments: Multiple lines comment begins with /* symbol and ends
with */. We can write any number of multiple lines comments in a program.
Preprocessing Commands
• Preprocessing commands are used to include header files and to define constants.
• #include statement to include the header file into our program.
• #define statement to define a constant. The preprocessing statements are used
according to the requirements
Global Declaration
• The global declaration is used to define the global variables, which are common
for all the functions after its declaration.
int main()
• main is a user-defined method which tells the compiler that this is the starting
point of the program execution.
• Here, int is a data type of a value that is going to return to the Operating System
after completing the main method execution. If we don't want to return any value,
we can use it as void.
Open Brace ( { )
• The open brace indicates the beginning of the block which belongs to the main
method. In C program, every block begins with a '{' symbol.
Local Declaration
• In this section, we declare the variables and functions that are local to the function or
block in which they are declared. The variables which are declared in this section are
valid only within the function or block in which they are declared.
Executable statements
• In this section, we write the statements which perform tasks like reading data,
displaying the result, calculations, etc., All the statements in this section are written
according to the requirements.
Closing Brace ( } )
• The close brace indicates the end of the block which belongs to the main method. In
C program every block ends with a '}' symbol.
User-defined function()
• The user-defined function implementation can also be performed before the main
method. Every user-defined function needs a function call to execute its statements.
Example of C Program
Identifiers
• One feature present in all computer languages is the identifier. Identifiers allow us to
name data and other objects in the program. Each identified object in the computer
is stored at a unique address.
• Rules for Identifiers:
Keywords
• Keywords are system defined identifiers. Keywords are reserved words of the
language. They have specific meaning in the language and cannot be used by the
programmer as variable or constant names.
• There are 32 Keywords in C Programming.
Variables
• Variables are named memory locations that have a type, such as integer or
character, which is inherited from their type.
• The type determines the values that a variable may contain and the operations
that may be used with its values.
Constants
• Constants are data values that cannot be changed during the execution of a
program. eg. const double PI = 3.14
• Here, PI is a constant. Basically, what it means is that, PI and 3.14 is same for this
program.
Integer constants
Floating-point constants
• A floating point constant is a numeric constant that has either a fractional form
or an exponent form.
• For example: 2.0,0.0000234,-0.22E-5
Character constants
String constants
• String constants are the constants which are enclosed in a pair of double-quote
marks.
• For example: "good" ,"x","Earth is round\n"
Escape Sequences
Sequences Character
\b Backspace
\f Form feed
\n Newline
\r Return
\t Horizontal tab
\v Vertical tab
\\ Backslash
\' Single quotation mark
\" Double quotation mark
\? Question mark
\0 Null character
Figure: Datatypes in C
• The integer datatype in C is used to store the whole numbers without decimal values.
Octal values, hexadecimal values, and decimal values can be stored in int data type in
C.
• Range: -2,147,483,648 to 2,147,483,647
• Size: 4 bytes
• Format Specifier: %d
• sizeof (short) ≤ sizeof (int) ≤ sizeof (long) ≤ sizeof (long long)
• The void data type in C is used to specify that no value is present. It does not
provide a result value to its caller.
• It has no values and no operations. It is used to represent nothing.
• Void is used in multiple ways as function return type, function arguments as void
etc.
• The size of the data types in C is dependent on the size of the architecture, so we
cannot define the universal size of the data types.
• For that, the C language provides the sizeof() operator to check the size of the data
types.
3. Structures
• Structure is a collection of logically related data items of different datatypes
grouped together under single name. Structure is a user defined datatype.
• Structure helps to build a complex datatype which is more meaningful than an
array. But, an array holds similar datatype record, when structure holds different
datatypes records.
• Two fundamental aspects of Structure:
o Declaration of Structure Variable
o Accessing of Structure Member
Example to Define Structure
Example:
Write a program to read and display student information using structure.
Array of Structure
• The array of structures in C are used to store information about multiple entities
of different data types.
Nested Structure
• For example, we have two structures named Address and Student. To make
Address nested to Student, we have to define Address structure before and
outside Student structure and create an object of Address structure inside Student
structure.
Example :
Write a program to read and display student information using nested of structure.
4. Self-referential structures
struct node
{
int val;
struct node *next;
};
• Here the structure node will contain two types of data an integer val and next
which is a pointer a node. Self-referential structure is the foundation of other
data structures.
• Such kinds of structures are used in different data structures such as to define
the nodes of linked lists, trees, etc.
Example 1:
Write a program to read and display student information using nested of
structure.
Example 2:
#include<stdio.h>
struct node {
int data;
struct node *link;
} n,b;
int main() {
n.data=3;
n.link=NULL;`
b.data=5;
b.link=NULL;
n.link=&b;
printf("%d",n.data);
printf("\n%d",n.link);
printf("\n%d",n.link->data);
}
Example:
Static Memory
• Static memory is memory that is reserved for variables before the program runs.
Allocation of static memory is also known as compile time memory allocation.
• C automatically allocates memory for every variable when the program is
compiled.
• For example, if you create an integer array of 20 students (e.g. for a summer
semester), C will reserve space for 20 elements which is typically 80 bytes of
memory (20 * 4).
• But when the semester starts, it turns out that only 12 students are attending.
Then you have wasted the space of 8 unused elements.
Dynamic Memory
• Dynamic memory is memory that is allocated after the program starts running.
Allocation of dynamic memory can also be referred to as runtime memory
allocation.
• Unlike with static memory, you have full control over how much memory is being
used at any time. You can write code to determine how much memory you need
and allocate it.
• Dynamic memory does not belong to a variable, it can only be accessed with
pointers.
malloc()
The name "malloc" stands for memory allocation. The malloc() function reserves
a block of memory of the specified number of bytes. And, it returns a pointer of
void which can be casted into pointers of any form.
Syntax of malloc()
Example
• The above statement allocates 400 bytes of memory. It's because the size of
float is 4 bytes. And, the pointer ptr holds the address of the first byte in the
allocated memory.
• The expression results in a NULL pointer if the memory cannot be allocated.
#include <stdio.h>
#include <stdlib.h> // Include for malloc and free
int main()
{
int n,i;
int *num;
printf("Enter the number of elements n:");
scanf("%d",&n);
num=(int*)malloc(n*sizeof(int));
if(num==NULL)
{
printf("Memory is full");
return 1;
}
for(i=0;i<n;i++)
{
printf("Enter the elements:");
scanf("%d",&num[i]);
printf("Address : %x\n",num+i);//print the address
}
printf("The entered values :");
for(i=0;i<n;i++)
{
printf("%d\n",num[i]);
}
return 1;
}
Output:
calloc()
The name "calloc" stands for contiguous allocation. The malloc() function allocates
memory and leaves the memory uninitialized, whereas the calloc() function
allocates memory and initializes all bits to zero.
Syntax of calloc()
Example:
#include <stdio.h>
#include <stdlib.h> // Include for malloc and free
int main()
{
int n,i;
int *num;
printf("Enter the number of elements n:");
scanf("%d",&n);
num=(int*)calloc(n,sizeof(int));
if(num==NULL)
{
printf("Memory is full");
return 1;
}
for(i=0;i<n;i++)
{
printf("Enter the elements:");
scanf("%d",&num[i]);
printf("Address : %x\n",num+i);//print the address
}
printf("The entered values :");
for(i=0;i<n;i++)
{
printf("%d\n",num[i]);
}
return 1;
}
OUTPUT:
2
3
4
free()
Dynamically allocated memory created with either calloc() or malloc() doesn't get
freed on their own. You must explicitly use free() to release the space.
Syntax of free()
free(ptr);
This statement frees the space allocated in the memory pointed by ptr.
realloc()
If the dynamically allocated memory is insufficient or more than required, you can
change the size of previously allocated memory using the realloc() function.
Syntax of realloc()
Example 3: realloc()
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,i,n1;
int *num;
printf("Enter n:");
scanf("%d",&n);
num=(int*)calloc(n,sizeof(int));
if(num==NULL)
{
printf("Memory is full");
return 1;
}
for(i=0;i<n;i++)
{
//scanf("%d",&num[i]);
printf("Address :%x\n",num+i);
}
for(i=0;i<n1;i++)
{
printf("Element = %d and Address is %x\n",num[i],num+i);
}
free(num);
return 0;
}
Output:
Enter n:5
Address :a26b50
Address :a26b54
Address :a26b58
Address :a26b5c
Address :a26b60
Enter the new size:6
Enter the new elements:
1
2
3
4
5
6
Element = 1 and Address is a26b50
Element = 2 and Address is a26b54
Element = 3 and Address is a26b58
Element = 4 and Address is a26b5c
Element = 5 and Address is a26b60
Element = 6 and Address is a26b64
7. Matrix multiplication
Algorithm:
Step 2: Enter the row and column of the first (a) matrix.
Step 3: Enter the row and column of the second (b) matrix
Step 6: Print the elements of the first (a) matrix in matrix form.
Step 7: Print the elements of the second (b) matrix in matrix form.
Step 11: Multiply the first (a) and second (b) matrix and store the element in the
third matrix (c)
#include <stdio.h>
#include <stdlib.h>
int main() {
int rows1, cols1, rows2, cols2;
int i, j;
return 0;
}
Output:
Enter the number of rows and columns for the first matrix: 2
2
Enter elements of the first matrix:
Element [0][0]: 1
Element [0][1]: 1
Element [1][0]: 1
Element [1][1]: 1
Enter the number of rows and columns for the second matrix: 2
2
Enter elements of the second matrix:
Element [0][0]: 1
Element [0][1]: 1
Element [1][0]: 1
Element [1][1]: 1
Result of matrix multiplication:
22
22
Based on the organizing method of data structure, non-primitive data structures are divided
into two types.
If a data structure organizes the data in sequential order, then that data structure is called a
Linear Data Structure.
If a data structure organizes the data in random order, then that data structure is called as
Non-Linear Data Structure.
, , , ,
Example: Tree Graph Dictionaries Heaps Tries, Etc.,
Example:
b. Suppose one wants to find the names of all members living in a particular area.
Again traverse and search the file to obtain the data.
c. Suppose one wants to obtain Address of a specific Person. Then one would
search the file for the record containing Name.
d. Suppose a member dies. Then one would delete his or her record from the
file.
e. Suppose a new person joins the organization. Then one would insert a record
into the file
would first need to search for the record in the file. Then perform the update
operation, i.e. change some items in the record with the new data.
g. Suppose one wants to find the number of members whose age is 65 or above.
Again one would traverse the file, counting such members.
• ADT refers to a set of data values and associated operations that are specified
accurately, independent of any particular implementation.
• The ADT consists of a set of definitions that allow us to use the functions while
hiding the implementation.
• Abstract in the context of data structures means everything except the detailed
specifications or implementation.
• Data type of a variable is the set of values that the variable can take. Examples:
Stacks, Queues, Linked List
• While modeling the problems the necessary details are separated out from the
unnecessary details. This process of modeling the problem is called abstraction.
• The model defines an abstract view to the problem. It focuses only on problem
related stuff and that you try to define properties of the problem.
• The ADT model has two different parts functions (public and private) and data
structures. Both are contained within the ADT model itself, and do not come within
the scope of the application program.
• Data are entered, accessed, modified and deleted through the external application
programming interface. For each ADT operation, there is an algorithm that
performs its specific task.
• The operation name and parameters are available to the application, and they
provide only an interface to the application.
1< log n < √n < n < n logn < n2 < n3 < ……………< 2n < 3n < …. <nn
upper bound
Big-Omega notation (Ω)
• This notation is used to describe the best case running time of algorithms and
concerned with large values of n.
1 < log n < √n < n < n logn < n2 < n3 < ……………< 2n < 3n < …. <nn
lower bound
Theta notation (θ)
Definition: A function t(n) is said to be in θ(g(n)), denoted t(n) ϵ θ(g(n)), if t(n) is bounded
both above and below by some positive constant multiples of g(n) for all large n. i.e., if
there exist some positive constant c1 and c2 and some non-negative integer n0 such that
1 < log n < √n < n < n logn < n2 < n3 < ……………< 2n < 3n < …. <nn
average bound
t(n) ≤ cg(n)
▪ There can be more than one algorithm to solve a particular problem. One may
require less memory space, while the other may require less CPU time to execute.
Thus, it is not uncommon to sacrifice one thing for the other.
▪ Hence, there exists a time–space trade-off among algorithms. So, if space is a big
constraint, then one might choose a program that takes less space at the cost of
more CPU time.
▪ On the contrary, if time is a major constraint, then one might choose a program
that takes minimum time to execute at the cost of more space.
YOUTUBE CHANNEL