0% found this document useful (0 votes)
42 views21 pages

DS Notes

Uploaded by

vijayalaxmib93
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views21 pages

DS Notes

Uploaded by

vijayalaxmib93
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

UNIT I:

An Introduction to Data Structures


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.

Figure 1: Representation of Data Items

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.

What s Data Structure?


Data Structure is a branch of Computer Science. The study of data structure allows us to
understand the organization of data and the management of the data flow in order to increase
the efficiency of any process or program. Data Structure is a particular way of storing and
organizing data in the memory of the computer so that these data can easily be retrieved and
efficiently utilized in the future when required. The data can be managed in various ways, like
the logical or mathematical model for a specific organization of data is known as a data
structure.
Understanding the Need for Data Structures
As applications are becoming more complex and the amount of data is increasing every
day, which may lead to problems with data searching, processing speed, multiple
requests handling, and many more. Data Structures support different methods to
organize, manage, and store data efficiently. With the help of Data Structures, we can
easily traverse the data items. Data Structures provide Efficiency, Reusability, and
Abstraction.

Why should we learn Data Structures?

1. Data Structures and Algorithms are two of the key aspects of Computer Science.
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.

Types of Data Structures

There are two types of data structures:


o Primitive data structure
o Non-primitive data structure

Primitive Data structure

The primitive data structures are primitive data types. The int, char, float, double, and
pointer are the primitive data structures that can hold a single value.
1. Primitive Data Structures are the data structures consisting of the numbers and
the characters that come in-built into programs.
2. These data structures can be manipulated or operated directly by machine-level
instructions.
3. Basic data types like Integer, Float, Character, and Boolean come under the
Primitive Data Structures.

Non-Primitive Data structure


1. Non-Primitive Data Structures are those data structures derived from Primitive
Data Structures.
2. These data structures can't be manipulated or operated directly by machine-level
instructions.
3. The focus of these data structures is on forming a set of data elements that is
either homogeneous (same data type) or heterogeneous (different data types).
4. Based on the structure and arrangement of data, we can divide these data
structures into two sub-categories -

a. Linear Data Structures


b. Non-Linear Data Structures

Linear Data Structure

The arrangement of data in a sequential manner is known as a linear data structure.


The data structures used for this purpose are Arrays, Linked list, Stacks, and Queues.
In these data structures, one element is connected to only one another element in a
linear form.
Based on memory allocation, the Linear Data Structures are further classified into two
types:

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 structure

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

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.
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. Create: Create is an operation used to reserve memory for the data elements of the
program. We can perform this operation using a declaration statement. The creation of
data structure can take place either during the following:

a. Compile-time
b. Run-time
For example, the malloc() function is used in C Language to create data
structure.
8. Selection: Selection means selecting a particular data from the available data. We can
select any particular data by specifying conditions inside the loop.
9. 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.
10. Splitting: The Splitting operation allows us to divide data into various subparts
decreasing the overall process completion time.

Advantages of Data structures


The following are the advantages of a data structure:
o Efficiency: If the choice of a data structure for implementing a particular ADT
is proper, it makes the program very efficient in terms of time and space.
o Reusability: The data structure provides reusability means that multiple client
programs can use the data structure.
o Abstraction: The data structure specified by an ADT also provides the level of
abstraction. The client cannot see the internal working of the data structure,
so it does not have to worry about the implementation part. The client can
only see the interface.
MEMORY ALLOCATION IN C

The process of reserving memory is called allocation. The way to allocate


memory depends on the type of memory.

C has two types of memory: Static memory and dynamic 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.

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.

The concept of dynamic memory allocation in c language enables the C


programmer to allocate memory at runtime. Dynamic memory allocation in c
language is possible by 4 functions of stdlib.h header file.
1. malloc()
2. calloc()
3. realloc()
4. free()

To allocate dynamic memory, you can use the malloc() or calloc() functions.
It is necessary to include the <stdlib.h> header to use them.
The malloc() and calloc() functions allocate some memory and return a
pointer to its address.

int *ptr1 = malloc(size);


int *ptr2 = calloc(amount, size);
The malloc() function has one parameter, size, which specifies how much
memory to allocate, measured in bytes.

The calloc() function has two parameters:

 amount - Specifies the amount of items to allocate


 size - Specifies the size of each item measured in bytes

malloc() allocates single block of requested memory.

calloc() allocates multiple block of requested memory.

realloc() reallocates the memory occupied by malloc() or calloc()


functions.

free() frees the dynamically allocated memory.

Difference between static and dynamic memory

Static memory allocation Dynamic memory allocation


memory is allocated at compile time. memory is allocated at run time.
memory can't be increased while memory can be increased while executing
executing program. program.
used in array. used in linked list

Now let's have a quick look at the methods used for dynamic memory allocation.

malloc() function in C
The malloc() function allocates single block of requested memory.

It doesn't initialize memory at execution time, so it has garbage value initially.

It returns NULL if memory is not sufficient.

The syntax of malloc() function is given below:


ptr=(cast-type*)malloc(byte-size)

EXAMPLE OF MALLOC() FUNCTION IN C


#include<stdio.h>
Struct student
{
Char name[10];
Int R.no;
Floar marks;
}
int main()
{
Struct student *p;
int n,i;
printf("Enter the value of n \n: ");
scanf("%d",&n);
p=(structstudent*)malloc(sizeofstructstudent*n); //memory allocated using malloc
for(i=0;i<n;i++)
{
printf("Enter I student details\n");
scanf(“%s %d %f”,&(p+i), &(p+i),&(p+i))
}
printf("The student details are\n ");
printf("Name\t R.no\t marks\n ");
for(i=0;i<n;++i)
{
Printf(“%s\t%d\t%f\n”,(p+i),(p+i),(p+i));
}
return 0;
}

calloc() function in C
The calloc() function allocates multiple block of requested memory.

It initially initialize all bytes to zero.

It returns NULL if memory is not sufficient.


The syntax of calloc() function is given below:
ptr=(cast-type*)calloc(number, byte-size)

Let's see the example of calloc() function.


#include<stdio.h>
#include<stdlib.h>
int main(){
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int)); //memory allocated using calloc
if(ptr==NULL)
{
printf("Sorry! unable to allocate memory");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
return 0;
}

Output
Enter elements of array: 3
Enter elements of array: 10
10
10
Sum=30

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)

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 in C language 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 in c language 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 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 nu
mber.
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
Address of p variable is fff4
Value of p variable is 50
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:

ADVERTISEMENT

o Increment
o Decrement
o Addition
o Subtraction
o Comparison

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.

The Rule to increment the pointer is given below:

1. new_address= current_address + i * size_of(data type)

Where i is the number by which the pointer get increased.

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.

Let's see the example of incrementing 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+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:

new_address= current_address - i * size_of(data type)

32-bit
For 32-bit int variable, it will be decremented by 2 bytes.

64-bit
For 64-bit int variable, it will be decremented by 4 bytes.

Let's see the example of decrementing pointer variable on 64-bit OS.

#include <stdio.h>
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 previ
ous 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:

new_address= current_address + (number * size_of(data type))

32-bit
For 32-bit int variable, it will add 2 * number.

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
After adding 3: Address of p variable is 3214864312

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.

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:

new_address= current_address - (number * size_of(data type))

32-bit
For 32-bit int variable, it will subtract 2 * number.

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);
}
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.

o Address + Address = illegal


o Address * Address = illegal
o Address % Address = illegal
o Address / Address = illegal
o Address & Address = illegal
o Address ^ Address = illegal
o Address | Address = illegal
o ~Address = illegal

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.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy