Data Structures
Data Structures
USING C
UNIT II
• When we do not know how much amount of memory would be needed for the program
beforehand.
• When we want data structures without any upper limit of memory space.
• When you want to use your memory space more efficiently. Example: If you have
allocated memory space for a 1D array as array[20] and you end up using only 10
memory spaces then the remaining 10 memory spaces would be wasted and this wasted
memory cannot even be utilized by other program variables.
• Dynamically created lists insertions and deletions can be done very easily just by
the manipulation of addresses whereas in case of statically allocated memory
insertions and deletions lead to more movements and wastage of memory.
• When you want you to use the concept of structures and linked list in programming,
dynamic memory allocation is a must
Swati Jain, Assistant Professor, VSIT,
VIPS - TC
DYNAMIC MEMORY ALLOCATION TECHNIQUES:
• 1. malloc:
• The malloc (memory allocation) function is used to allocate a specified number of
bytes in memory.
• When memory is allocated successfully, it returns a pointer to that block, otherwise
it returns NULL.
• By dividing the necessary number of elements by each one's individual size, the
block's size is calculated.
• For example:
• int* ptr = (int*) malloc(5 * sizeof(int)); // Allocates memory for 5 integers
• 2. calloc:
• “calloc” or “contiguous allocation” method in C is used to dynamically allocate
the specified number of blocks of memory of the specified type.
• It is very much similar to malloc() but has two different points and these are:
• It initializes each block with a default value ‘0’.
• It has two parameters or arguments as compare to malloc().
• int* ptr = (int*) calloc(5, sizeof(int)); // Allocates memory for an
array of 5 integers
• 3. realloc()
• “realloc” or “re-allocation” method in
C is used to dynamically change the memory
allocation of a previously allocated
memory.
• In other words, if the memory previously
allocated with the help of malloc or
calloc is insufficient, realloc can be
used to dynamically re-allocate memory.
• Re-allocation of memory maintains the
already present value and new blocks will
be initialized with the default garbage
value.
• ptr = realloc(ptr, newSize); // where
ptr is reallocated with new size 'newSize'.
Swati Jain, Assistant Professor, VSIT,
VIPS - TC
DYNAMIC VS STATIC MEMORY ALLOCATION
• A linked list is a linear data structure, in which the elements are not stored at
contiguous memory locations.
• In simple words, a linked list consists of nodes where each node contains a data
field and a reference(link) to the next node in the list.
• The elements in a linked list are linked using pointers as shown in the below image:
• It is basically chains of nodes, each node contains information such as data and a pointer to
the next node in the chain. In the linked list there is a head pointer, which points to the
first element of the linked list, and if the list is empty then it simply points to null or
nothing.
Swati Jain, Assistant Professor, VSIT,
VIPS - TC
LINKED LIST
• Traversal of items can be done in the forward direction only due to the
linking of every node to its next node.
• A circular linked list is a type of linked list in which the first and
the last nodes are also connected to each other to form a circle, there
is no NULL at the end.
void begdelete()
{
struct node *ptr;
if(head == NULL)
{
printf("\nList is empty");
}
else
{
ptr = head;
head = ptr->next;
free(ptr);
printf("\n Node deleted from the begining ...");
}
}
else
{
ptr = head;
while(ptr->next != NULL)
{
ptr1 = ptr;
ptr = ptr ->next;
} Swati Jain, Assistant Professor, VSIT,
VIPS - TC
ptr1->next = NULL;
SINGLY LINKED LIST- DELETION AT A SPECIFIC NODE
if(ptr == NULL)
{
printf("\nThere are less than %d elements in the list..\n",loc);
return;
}
}
ptr1 ->next = ptr ->next;
free(ptr);
printf("\nDeleted %d node ",loc);
}
Swati Jain, Assistant Professor, VSIT,
VIPS - TC
TRAVERSING IN SINGLY LINKED LIST
void traverse()
{
struct node *ptr;
ptr = head;
if(ptr == NULL)
{
printf("Empty list..");
}
else
{
printf("printing values . . . . .\n");
while (ptr!=NULL)
{
printf("\n%d",ptr->data);
ptr = ptr -> next;
}
}
}
void search()
{
struct node *ptr;
int item,i=0,flag=1;
ptr = head;
if(ptr == NULL)
{
printf("\nEmpty List\n");
}
else
{
printf("\nEnter item which you want to search?\n");
scanf("%d",&item);
while (ptr!=NULL)
{
if(ptr->data == item)
{
printf("item found at location %d ",i+1);
flag=0;
}
Swati Jain, Assistant Professor, VSIT,
VIPS - TC
REVERSE A LINKED LIST
h = head;
swapped = 0;
/* Allocate memory */
one = malloc(sizeof(struct node));
two = malloc(sizeof(struct node));
three = malloc(sizeof(struct node));
/* Connect nodes */
one->next = two;
one->prev = NULL;
Let's add a node with value 6 at the beginning of the doubly linked list we made before.
1. Create a new node
•allocate memory for newNode
•assign the data to newNode.
// point next of newNode to the first node of the doubly linked list
newNode->next = (*head);
// point previous of the first node (now first node is the second node) to newNode
if ((*head) != NULL)
(*head)->prev = newNode;
Let's add a node with value 6 after node with value 1 in the doubly linked list.
1. Create a new node
•allocate memory for newNode
•assign the data to newNode.
3. Set the prev pointer of new node and the next node
•assign the value of prev of next node to the prev of newNode
•assign the address of newNode to the prev of next node
Let's add a node with value 6 after node with value 1 at the end of doubly linked list.
1. Create a new node
•allocate memory for newNode
•assign the data to newNode.
// if the linked list is not empty, traverse to the end of the linked list
while (temp->next != NULL)
temp = temp->next;
Finally, free the memory of del_node. And, the linked will look like this
if (head == del_node)
head = del_node->next;
if (del_node->prev != NULL)
del_node->prev->next = del_node->next;
free(del_node);
If del_node is an inner node (second node), we must have to reset the value of next and prev of the
nodes before and after the del_node.
For the node before the del_node (i.e. first node)
Assign the value of next of del_node to the next of the first node.
For the node after the del_node (i.e. third node)
Assign the value of prev of del_node to the prev of the third node.
Finally, we will free the memory of del_node. And, the final doubly linked list looks like this.
if (del_node->next != NULL)
del_node->next->prev = del_node->prev;
if (del_node->prev != NULL)
del_node->prev->next = del_node->next;
In this case, we are deleting the last node with value 3 of the doubly linked list.
Here, we can simply delete the del_node and make the next of node before del_node point
to NULL.
if (del_node->prev != NULL)
del_node->prev->next = del_node->next;
• A circular linked list is a type of linked list in which the first and the last nodes are also
connected to each other to form a circle.
• There are basically two types of circular linked list:
• 1. Circular Singly Linked List
• Here, the address of the last node consists of the address of the first node.
Let's see how we can represent a circular linked list on an algorithm/code. Suppose we have a
linked list:
/* Allocate memory */
one = malloc(sizeof(struct node));
two = malloc(sizeof(struct node));
three = malloc(sizeof(struct node));
/* Connect nodes */
one->next = two;
two->next = three;
three->next = one;
/* Save address of third node in last */ Swati Jain, Assistant Professor, VSIT,
VIPS - TC
last = three;
INSERTION ON A CIRCULAR LINKED LIST
• A header node is a special node that is found at the beginning of the list. A list that contains
this type of node, is called the header-linked list. T
• his type of list is useful when information other than that found in each node is needed. For
example, suppose there is an application in which the number of items in a list is often
calculated. Usually, a list is always traversed to find the length of the list. However, if the
current length is maintained in an additional header node that information can be easily
obtained.
• Types of Header Linked List:
• Grounded Header Linked List It is a list whose last node contains the NULL pointer. In the
header linked list the start pointer always points to the header node. start -> next =
NULL indicates that the grounded header linked list is empty. The operations that are
possible on this type of linked list are Insertion, Deletion, and Traversing.
• Circular Header Linked List A list in which last node points back to the header node is called
circular linked list. The chains do not indicate first or last nodes. In this case, external
pointers provide a frame of reference because last node of a circular linked list does not
contain the NULL pointer. The possible operations on this type of linked list are Insertion,
Deletion and Traversing. Swati Jain, Assistant Professor, VSIT,
VIPS - TC
HEADER LINKED LIST
•From the polynomial represented by F(x) it is clear that this polynomial has two
parts, coefficient and exponent, where, x is formal parameter. Hence, we can say that a
polynomial is sum of terms, each of which consists of a coefficient and an exponent.
•The computer implementation requires implementing polynomials as a list of pair of
coefficient and exponent. Each of these pairs will constitute a structure, so a polynomial will be
represented as a list of structures.
•If one wants to represent F(x) with help of linked list then the list will contain 5 nodes. When
we link each node we get a linked list structure that represents polynomial F(x).
// Empty List
struct node* start = NULL;
• Write a program in C to create a singly linked list of n nodes and count the number of nodes.
• Write a C program that converts a singly linked list into an array and returns it.
• Write a C program to merge two sorted singly linked lists into a single sorted linked list.
• Write a C program to delete alternate nodes of a singly linked list.