Data Structure 1 Unit
Data Structure 1 Unit
Since the invention of computers, people have been using the term "Data" to refer to
Computer Information, either transmitted or stored. However, there is data that exists in order
types as well. Data can be numbers or texts written on a piece of paper, in the form of bits and
bytes stored inside the memory of electronic devices, or facts stored within a person's mind. As
the world started modernizing, this data became a significant aspect of everyone's day-to-day
life, and various implementations allowed them to store it differently.
Data is a collection of facts and figures or a set of values or values of a specific format that
refers to a single set of item values. The data items are then classified into sub-items, which is
the group of items that are not known as the simple primary form of the item.
Let us consider an example where an employee name can be broken down into three sub-items:
First, Middle, and Last. However, an ID assigned to an employee will generally be considered a
single item.
In the example mentioned above, the items such as ID, Age, Gender, First, Middle, Last, Street,
Locality, etc., are elementary data items. In contrast, the Name and the Address are group data
items.
vijayalaxmi s b 1
2. Data Structures allow us to organize and store data, whereas Algorithms allow us to
process that data meaningfully.
3. Learning Data Structures and Algorithms will help us become better Programmers.
4. We will be able to write code that is more effective and reliable.
5. We will also be able to solve problems more quickly and efficiently.
vijayalaxmi s b 2
a. Linear Data Structures
b. Non-Linear Data Structures
1. Static Data Structures: The data structures having a fixed size are known as Static Data
Structures. The memory for these data structures is allocated at the compiler time, and
their size cannot be changed by the user after being compiled; however, the data stored in
them can be altered.
The Array is the best example of the Static Data Structure as they have a fixed size, and
its data can be modified later.
2. Dynamic Data Structures: The data structures having a dynamic size are known as
Dynamic Data Structures. The memory of these data structures is allocated at the run
time, and their size varies during the run time of the code. Moreover, the user can change
the size as well as the data elements stored in these data structures at the run time of the
code.
Linked Lists, Stacks, and Queues are common examples of dynamic data structures
Non-Linear Data Structures are data structures where the data elements are not arranged in
sequential order. Here, the insertion and removal of data are not feasible in a linear manner.
There exists a hierarchical relationship between the individual data items. Example: tree, graph
Basic Operations of Data Structures
In the following section, we will discuss the different types of operations that we
can perform to manipulate data in every data structure:
1. Traversal: Traversing a data structure means accessing each data element exactly once
so it can be administered. For example, traversing is required while printing the names of
all the employees in a department.
2. Search: Search is another data structure operation which means to find the location of
one or more data elements that meet certain constraints. Such a data element may or may
not be present in the given set of data elements. For example, we can use the search
operation to find the names of all the employees who have the experience of more than 5
years.
3. Insertion: Insertion means inserting or adding new data elements to the collection. For
example, we can use the insertion operation to add the details of a new employee the
company has recently hired.
4. Deletion: Deletion means to remove or delete a specific data element from the given list
of data elements. For example, we can use the deleting operation to delete the name of an
employee who has left the job.
vijayalaxmi s b 3
5. Sorting: Sorting means to arrange the data elements in either Ascending or Descending
order depending on the type of application. For example, we can use the sorting operation
to arrange the names of employees in a department in alphabetical order or estimate the
top three performers of the month by arranging the performance of the employees in
descending order and extracting the details of the top three.
6. Merge: Merge means to combine data elements of two sorted lists in order to form a
single list of sorted data elements.
7. Selection: Selection means selecting a particular data from the available data. We can
slect any particular data by specifying conditions inside the loop.
8. Update: The Update operation allows us to update or modify the data in the data
structure. We can also update any particular data by specifying some conditions inside
the loop, like the Selection operation.
9. Splitting: The Splitting operation allows us to divide data into various subparts
decreasing the overall process completion time.
vijayalaxmi s b 4
10. We can also develop software that can render graphics using Data Structures. (For
example, a web browser or 3D rendering software).
MEMORY ALLOCATION IN C
The process of reserving memory is called allocation. The way to allocate memory depends on
the type of memory.
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):
Example:
int students[20];
printf("%lu", sizeof(students)); // 80 bytes
But when the semester starts, it turns out that only 12 students are attending. Then you have
wasted the space of 8 unused elements.
Since you are not able to change the size of the array, you are left with unnecessary reserved
memory.
Note that the program will still run, and it is not damaged in any way. But if your program
contains a lot of this kind of code, it may run slower than it optimally could.
If you want better control of allocated memory, take a look at Dynamic Memory below.
vijayalaxmi s b 5
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.
}
printf("Entered values);
{
prntf(“%d”, *(ptr+i))
}
free(ptr);
return 0;
}
2. calloc() function
calloc is contiguous memory allocation.
The calloc() function allocates multiple block of requested memory.
The calloc() function has two parameters:
vijayalaxmi s b 7
}
printf("Enter elements : ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
}
printf("Entered values);
{
prntf(“%d”, *(ptr+i))
}
free(ptr);
return 0;
}
3. realloc() function in C
If memory is not sufficient for malloc() or calloc(), you can reallocate the memory by
realloc() function. In short, it changes the memory size.
The realloc () function modifies the allocated memory size to a new size by the malloc()
and calloc() functions.
If enough space doesn't exist in the current block's memory to expand, a new block is
allocated for the total size of the reallocation, then copies the existing data to the new
block and frees the old block
Let's see the syntax of realloc() function.
ptr=realloc(ptr, new-size)
4. free () function in C
The memory occupied by malloc() or calloc() functions must be released by calling free()
function. Otherwise, it will consume memory until program exit.
Pointers in C
The pointer is a variable which stores the address of another variable. this variable can be
of type int, char, array, function, or any other pointer. the size of the pointer depends on the
architecture. However, in 32-bit architecture the size of a pointer is 2 byte.
Consider the following example to define a pointer which stores the address of an integer.
int n = 10;
int* p = &n; // Variable p of type pointer is pointing to the address of the variable n
of type integer.
Declaring a pointer
The pointer can be declared using * (asterisk symbol). It is also known as indirection pointer
used to dereference a pointer.
int *a; //pointer to int
char *c; //pointer to char
Pointer Initialization
vijayalaxmi s b 8
Pointer initialization is the process where we assign some initial value to the pointer variable. We
generally use the ( & ) addressof operator to get the memory address of a variable and then store
it in the pointer variable.
Example
We can also declare and initialize the pointer in a single step. This method is called pointer
definition as the pointer is declared and initialized at the same time.
Example
Pointer Example
An example of using pointers to print the address and value is given below.
As you can see in the above figure, pointer variable stores the address of number variable, i.e.,
fff4. The value of number variable is 50. But the address of pointer variable p is aaa3.
By the help of * (indirection operator), we can print the value of pointer variable p.
Let's see the pointer example as explained for the above figure.
#include<stdio.h>
int main()
{
int number=50;
int *p;
p=&number; //stores the address of number variable
printf("Address of p variable is %x \n",p);
// p contains the address of the number therefore printing p gives the address of number.
printf("Value of p variable is %d \n",*p);
// As we know that * is used to dereference a pointer therefore if we print
*p, we will get the value stored at the address contained by p.
return 0;
}
Output
Address of number variable is fff4
vijayalaxmi s b 9
Address of p variable is fff4
Value of p variable is 50
Pointer is a special type of variable that is used to store the memory address of another
variable. A normal variable contains the value of any type like int, char, float etc, while a pointer
variable contains the memory address of another variable.
Here, we are going to learn how can we access the value of another variable using the pointer
variable?
Here, we have declared a normal integer variable num and pointer variable ptr, ptr is being
initialized with the address of num and finally getting the value of num using pointer
variable ptr.
#include <stdio.h>
int main(void)
{
For example, to print the memory address of 'x', use printf("%p", p); .
Here's an example demonstrating how to access the memory address of an integer variable and store
it in a pointer:
#include<stdio.h>
int main()
{
int x = 42;
int *p = x;
printf("Memory address of x: %p\n", p);
return 0;
}
When we want to point at multiple variables or memories of the same data type in a C program,
we use an array of pointers.
Let us assume that a total of five employees are working at a cheesecake factory. We can store
the employees’ names in the form of an array. Along with this, we also store the names of
employees working at the office, the library, and the shoe store.
vijayalaxmi s b 11
The syntax for declaring an array of pointers would be:
int *arr[55]
This one is an array of a total of 55 pointers. In simple words, this array is capable of holding the
addresses a total of 55 integer variables. Think of it like this- the ary[0] will hold the address of
one integer variable, then the ary[1] will hold the address of the other integer variable, and so on
#include<stdio.h>
#define SIZE 10
int main()
{
int *arr[3];
int p = 40, q = 60, r = 90, i;
arr[0] = &p;
arr[1] = &q;
arr[2] = &r;
for(i = 0; i < 3; i++)
{
printf(“For the Address = %d\t the Value would be = %d\n”, arr[i], *arr[i]);
}
return 0;
}
The output generated out of the program mentioned above would be like this:
For the Address = 387130656 the Value would be = 40
For the Address = 387130660 the Value would be = 60
For the Address = 387130664 the Value would be = 90
Pointer Arithmetic in C
We can perform arithmetic operations on the pointers like addition, subtraction, etc. However, as
we know that pointer contains the address, the result of an arithmetic operation performed on the
pointer will also be a pointer if the other operand is of type integer. In pointer-from-pointer
subtraction, the result will be an integer value. Following arithmetic operations are possible on
the pointer in C language:
o Increment
o Decrement
o Addition
o Subtraction
vijayalaxmi s b 12
Incrementing Pointer in C
If we increment a pointer by 1, the pointer will start pointing to the immediate next location. This
is somewhat different from the general arithmetic since the value of the pointer will get increased
by the size of the data type to which the pointer is pointing.
We can traverse an array by using the increment operation on a pointer which will keep pointing
to every element of the array, perform some operation on that, and update itself in a loop.
32-bit
For 32-bit int variable, it will be incremented by 2 bytes.
64-bit
For 64-bit int variable, it will be incremented by 4 bytes.
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p+1;
printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incremented by
4 bytes.
return 0;
}
Decrementing Pointer in C
Like increment, we can decrement a pointer variable. If we decrement a pointer, it will start
pointing to the previous location. The formula of decrementing the pointer is given below:
64-bit
For 64-bit int variable, it will be decremented by 4 bytes.
#include <stdio.h>
vijayalaxmi s b 13
void main(){
int number=50;
int *p; //pointer to int
p=&number; //stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p-1;
printf("After decrement: Address of p variable is %u \n",p);
// P will now point to the immidiate previous location.
}
Output
Address of p variable is 3214864300
After decrement: Address of p variable is 3214864296
C Pointer Addition
We can add a value to the pointer variable. The formula of adding value to pointer is given
below:
64-bit
For 64-bit int variable, it will add 4 * number.
Let's see the example of adding value to pointer variable on 64-bit architecture.
#include<stdio.h>
int main(){
int number=50;
int *p; //pointer to int
p=&number; //stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p+3; //adding 3 to pointer variable
printf("After adding 3: Address of p variable is %u \n",p);
return 0;
}
Output
Address of p variable is 3214864300
As you can see, the address of p is 3214864300. But after adding 3 with p
variable, it is 3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it
increments 12. But if we were using 32-bit architecture, it was incrementing to 6 only, i.e.,
2*3=6. As integer value occupies 2-byte memory in 32-bit OS.
vijayalaxmi s b 14
C Pointer Subtraction
Like pointer addition, we can subtract a value from the pointer variable. Subtracting any number
from a pointer will give an address. The formula of subtracting value from the pointer variable is
given below:
64-bit
For 64-bit int variable, it will subtract 4 * number.
Let's see the example of subtracting value from the pointer variable on 64-bit architecture.
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p-3; //subtracting 3 from pointer variable
printf("After subtracting 3: Address of p variable is %u \n",p);
return 0;
}
Output
Address of p variable is 3214864300
After subtracting 3: Address of p variable is 3214864288
You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the previous
address value.
However, instead of subtracting a number, we can also subtract an address from another address
(pointer). This will result in a number. It will not be a simple arithmetic operation, but it will
follow the following rule.
If two pointers are of the same type,
Address2 - Address1 = (Subtraction of two addresses)/size of data type which pointer points
Consider the following example to subtract one pointer from an another.
#include<stdio.h>
void main ()
{
int i = 100;
int *p = &i;
int *temp;
temp = p;
p = p + 3;
printf("Pointer Subtraction: %d - %d = %d",p, temp, p-temp);
}
vijayalaxmi s b 15
Output
Pointer Subtraction: 1030585080 - 1030585068 = 3
Illegal arithmetic with pointers
There are various operations which can not be performed on pointers. Since, pointer stores
address hence we must ignore the operations which may lead to an illegal address, for example,
addition, and multiplication. A list of such operations is given below.
Advantage of pointer
1) Pointer reduces the code and improves the performance, it is used to retrieving strings,
trees, etc. and used with arrays, structures, and functions.
2) We can return multiple values from a function using the pointer.
3) It makes you able to access any memory location in the computer's memory.
Disadvantage of pointer
Uninitialized pointers might cause segmentation fault.
Dynamically allocated block needs to be freed explicitly.
Otherwise, it would lead to memory leak.
Pointers are slower than normal variables.
If pointers are updated with incorrect values, it might lead to memory corruption.
Usage of pointer
There are many applications of pointers in c language.
1) Dynamic memory allocation
In c language, we can dynamically allocate memory using malloc() and calloc() functions where
the pointer is used.
2) Arrays, Functions, and Structures
Pointers in c language are widely used in arrays, functions, and structures. It reduces the code
and improves the performance.
vijayalaxmi s b 16
vijayalaxmi s b 17