Presentation For Data Structure New
Presentation For Data Structure New
As applications are getting complexes and amount of data is increasing day by day, there may arise the
following problems: Processor speed, Data Search and Multiple requests.
In order to solve the above problems, data structures are used.
Data Structure can be defined as the group of data elements which provides an efficient way of storing and
organizing data in the computer.
Data Structures are widely used in almost every aspect of Computer Science i.e. Operating System, Compiler
Design, Artificial intelligence, Graphics and many more.
Data Structure Classification
Structure
Structure in C is a user-defined data type that can store related information (even of different data types) together. Each
element of a structure is called a member.
the syntax to define the structure in c:
struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
};
The deceleration(definition) of the above structure, it says the compiler that what variables it will contain,
but don't allocate memory.
Memory is allocated only when we declare the variables of the structure.
There are two ways to declare structure variable:
1. By struct keyword within main() function: struct structure_name structure_variable_name;
2. By declaring a variable at the time of defining the structure.
There are two ways to access structure members:
1. By . (member or dot operator)
A structure member variable is generally accessed using a '.' (dot) operator.
The syntax of accessing a structure or a member of a structure is:
struct_var.member_name;
2. By -> (structure pointer or arrow operator) :
A structure member linked with pointer variable is generally accessed using a ‘->' (arrow) operator.
Typedef
The typedef is a keyword used in C language to assign alternative names to existing data type.
The general syntax of using the typedef keyword is:
typedef existing_data_type new_data_type;
Typedef can be used to simplify the real commands as per our need.
the scope of the declarations depends on the location of the typedef statement.
typedef struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
} type_name ;
Nested Structures
A structure that contains another structure as its member is called a nested structure.
The structure can be nested in the following two ways:
By separate structure By Embedded structure
struct structure_name1 struct structure_name1
{ {
data_type member1; data_type member1;
data_type member2; data_type member2;
. .
data_type memeberN; data_type memeberN;
}; struct structure_name2
struct structure_name2 {
{ data_type member1;
data_type member1; data_type member2;
data_type member2; .
. data_type memeberN;
data_type memeberN; } struct_variable2;
struct structure_name1 struct_variable1; };
};
Arrays Of Structures
An array of structures in C can be defined as the collection of multiple structures variables where each
variable contains information about different entities.
To declare Arrays of Structure variable:
struct structure_name structure_variable_name[ ];
Self-Referential Structures
A self-referential structure is one of the data structures which refer to the pointer (points) to another structure
of the same type.
struct name {
member 1;
member 2;
...
struct name *pointer;
};
It used in the many of the data structures like in Linked List, Trees, Graphs, Heap etc.
Unions
Union is a user-defined data type that allows different data types to be stored in the same memory locations.
The memory occupied by a union will be large enough to hold the largest member of the union.
Union provides an efficient way of reusing the memory location, as only one of its members can be accessed
at a time.
Advantage of union is occupies less memory because it allocates one common storage space for all its
members(occupies the size of the largest member only). However, Structure allocates storage space for all its
members separately.
Disadvantage of union is only the last entered data can be stored in the union. It overwrites the data
previously stored in the union.
We can’t access all member values at the same time in union. But, structure can access all member values at
the same time.
A union is used almost in the same way you would declare and a structure.
union union–name
{
data_type var–name;
data_type var–name;
..................
};
the difference between structures and unions while initializing values. The fields of a union cannot be initialized all at once.
union union–name P2 ={4,5}; Illegal in case of unions
Linked list
Arrays vs Linked list
An array is a data structure used to process multiple elements with the same data type when a number of
such elements are known.
Array is linear, sequential and contiguous collection of elements which can be addressed using index.
Linked list is linear, sequential and non-contiguous collection of nodes, each node store the reference to
next node.
(Static Vs dynamic size)Size of an array is defined statically at the compile time where as linked list grows
dynamically at run time based on need.
(Memory allocation)An array is given contiguous memory in system. So, if you know the address of any
of the element in array, you can access other elements based position of the element
(Memory allocation)Linked list are not store contiguous on memory, nodes are scattered around on
memory. So you may traverse forward in linked list, given node (using next node reference), but you can
not access nodes prior to it.
Memory requirement
Operation efficiency
https://algorithmsandme.com/difference-between-array-and-linked-lists/
Array Linked list
The size of the arrays is fixed: So we must know the upper Dynamic size, There is no need to define an initial size.
limit on the number of elements in advance.
Inserting a new element and deletion elements in an array Ease of insertion/deletion, Items can be added or
are expensive. removed from the middle of the list
Elements of the array can be randomly accessed by using Random access is not allowed. We have to access
the index, do not depend on the number of elements on elements sequentially starting from the first node,
array. depends on the number of elements on linked list.
Due to memory requirement, array is less memory space Extra memory space for a pointer is required with each
requirement. element of the list.
Due to memory utilization less efficient use memory space In linked list more efficiently dynamically use memory
in array. space(there is no wastage of memory space in linked list)
array elements are contiguous locations linked list elements are not stored at a contiguous
location; the elements are linked using pointers.
Linked List
A linked list is a linear of data structure that consists of sequence of nodes that are randomly stored in the
memory
It is a set of dynamically allocated nodes. The number of nodes in a linked list is not fixed and can grow and
shrink on demand.
A node is a collection of two sub-elements or parts. A data part that stores the element(it may be a number,
string or any object like structure) and a next part is a pointer that points to the next node in the sequence.
A head pointer is used to track the first element in the linked list, therefore, it always points to the first
element.
Last Node of the linked list contains NULL in the next part. If the pointer is NULL, then it is the last node in
the list.
Linked lists provide an efficient way of storing related data and perform basic operations such as
insertion, deletion, and updating of information at the cost of extra space required for storing address of the
next node
the syntax to implement a linked list in c:
typedef struct node {
int data;
struct node * next;
};
Types Of Linked Lists
1. Singly Linked List:
Singly linked list is a collection of nodes linked together in a sequential way.
Singly Linked List does not store any pointer(any reference) to the previous node.
To perform any operation on a linked list we must keep track/reference of the first node which may be
referred by head pointer variable.
In singly linked list address field of last node must contain a NULL value specifying end of the list.
The operations we can perform on singly linked lists are insertion, deletion and traversal.
Create A Singly Linked List:
To defining or create node structure.
struct node {
int data; //data is the data you want to store in list
struct node * next; // the *next will store location of next node if exists otherwise NULL
};
Declare a pointer to node type variable to store link of first node of linked list.
struct node *head;
Allocate memory for first node:
head = (struct node*)malloc(sizeof(struct node));
Check whether the list is empty or not. If the condition head == NULL true, insert the first node of a singly
linked list with store data into the data part of the node:
head->data = data;
Make sure that the next pointer field of head node should point to NULL :
head-> next = NULL; //
The condition head == NULL become false and the node will be inserted in the list. Create new node and
temporary(temp) node:
struct node *newNode, * temp;
Initialize the pointer temp to head:
temp = head; // temp initialize with first that stores the address of the first node of the list
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node(Link the data part)
Make sure that the next pointer field of newNode node should point to NULL:
newNode -> next = NULL;
Connect the previous node with newly created node i.e. Connect the next pointer field of temp with the
newNode :
temp ->next = newNode; // Link the previous node with newly created node
Move the temp ahead i.e. temp should point to newNode:
temp = newNode;
Traversing A singly Linked List:
Traversing means visiting each node of the list once in order to perform some operation on that.
Create a temporary(temp) node and Assign reference of head node to it:
struct node *temp;
temp = head; // initialize temp with the address of head
Traverse the linked list until last node:
do {
printf("Data %d = %d\n", n, temp->data);
temp = temp ->next;
n++;
}while(temp != NULL);
Inserting A New Node In A Singly Linked List
There are three different possibilities for inserting a node into a linked list.
1. Insertion at the beginning of the list:
To define or create node structure.
struct node {
int data; //data is the data you want to store in list
struct node * next; // the *next will store location of next node if exists otherwise NULL
};
Create the insertion at the bagging of the list function.
Declare a pointer to node type variable to store link of first node of linked list and Create a new node:
struct node *head, * newNode ;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node*)malloc(sizeof(struct node))
newNode->data = item;// Assign data value to newly created node
Make the link part of the new node pointing to the existing first node of the list:
newNode->next = head;
Make the new node as the first node of the list:
head = newNode;
2. Insertion at the end of the list:
Create a function which the insertion at the end of the list.
Create a new node:
struct node *newNode ;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node(Link the data part)
A new node make sure that the address part of the new node points to NULL:
newNode->next=NULL;
Check whether the list is empty or not. if the condition head == NULL is true, add the first new node. Make
the new node as the first node of the list:
head = newNode;
The condition head == NULL become false and the node will be inserted in last. Declare a temporary
pointer(temp) to node type variable in order to search the last node:
struct node *temp;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse to the last node of the linked list:
while (temp→ next != NULL){
temp = temp → next;}
At the end of the loop, the temp will be pointing to the last node of the list. We need to make the next part of
the temp node point to the new node (newNode):
temp->next = newNode; // Link address part
3. Insertion Of A New Node At Any Position Of The List:
Create a function which the insertion at any position of the list.
Declere the variable(position) to insert the location of the new node:
int position;
Create a new node and declare a temporary pointer(temp) to node type variable in order to search the last
node:
struct node *newNode, *temp;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node(Link the data part)
Insert the location of the new node :
scanf("%d",&position);
A new node make sure that the address part of the new node points to NULL:
newNode->next=NULL;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse to the n-1th position of the linked list :
for(i=2; i<=position-1; i++)
{
temp = temp->next;
if(temp == NULL)
break;
}
The temp will be pointing to the n-1th node of the list and connect the new node with the n+1th node of the list:
newNode->next = temp->next; // the new node should also point to the same node
// that the n-1th node is pointing to
We need to make the next part of the temp node (which is currently the n-1 th node of the list) point to the new
node (newNode):
temp->next = newNode; // Link address part
Deleting A Node From A Linked List
There are three different possibilities for deleting a node from a linked list.
1. Deleting The First Node From A Linked List:
Create a function which deletion of the first node from the list .
Declare a temporary pointer(temp) to node type variable :
struct node *temp;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Move the head to the second node of the linked list:
head = temp->next;
Free the memory occupied by the first node:
free(temp); // free the pointer temp which was pointing to the head node of the list
2. Deleting the Last Node from a Linked List:
Create a function which deletion of the last node from the list .
Create two new temporary nodes(temp and secondLastNode):
struct node *temp, *secondLastNode;
Temp and secondLastNode are made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
secondLastNode = head; // secondLastNode initialize with head
Traverse to the last node of the linked list:
while (temp→ next != NULL){
secondLastNode = temp
temp = temp → next;}
At the end of the loop, the temp will be pointing to the last node of the list. Disconnect link of second last
node with last node.
secondLastNode ->next = NULL;
Free the memory occupied by the last node:
free(temp); // Delete the last node
3. Deletion In Singly Linked List After The Specified Node:
Create a function which deletion of a node any position from the list .
Declare the variable(position) to insert the location of the new node:
int position;
Create two new temporary nodes(temp and prevNode):
struct node *temp, prevNode;
Insert the location of the new node :
scanf("%d",&position);
Temp and prevNode are made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
prevNode = head; // prevNode initialize with head
Traverse to the n-1th position of the linked list :
for(i=2; i<=position; i++)
{
prevNode = temp;
temp = temp->next;
if(temp == NULL)
break;
}
At the end of the loop, if the condition temp!=NULL is true, to delete data at the given position. The temp will
be pointing to the nth node of the list and Reconnect the n-1th node with the n+1th node :
prevNode ->next = temp->next;
temp->next = NULL;
Free the memory occupied by the nth node:
free(temp); //Delete nth node
If the condition temp!=NULL is false, to print unable to delete data at the given position on the screen and
make exit.
4. delete all nodes of Singly Linked List:
Create a new temporary(temp) node:
struct node *temp;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse until the last node of the linked list and Free the memory occupied by every node:
while (head != NULL)
head= head → next;
free(temp);
2. Doubly Linked List:
Doubly Linked List is a collection of nodes linked together in a sequential way.
A doubly linked list is a more complex type of linked list which contains a pointer to the next as well as the
previous node in the sequence.
It consists of three parts: data, a pointer to the next node, and a pointer to the previous node.
Doubly linked list allows the traversal of nodes in both direction hence we can keep track of both first and last
nodes.
The prev part of the first node and the next part of the last node will always contain null indicating end in each
direction.
The basic structure (structure of a node) of a doubly linked
list contains a data field and two address fields:
struct node {
int data; // Data field
struct node * prev; // Address of previous node
struct node * next; // Address of next node
};
Advantages of Doubly linked list:
Allows traversal of nodes in both direction(from the start node to the end node as well as from the end node to
the start node) which is not possible in singly linked list.
Deletion and insertion operations are easy to implementation in a doubly linked list than a singly linked list
Reversing the list is simple and straightforward.
Can allocate or de-allocate memory easily when required during its execution.
It is one of most efficient data structure to implement when traversing in both direction is required.
Disadvantages of Doubly linked list
It uses extra memory when compared to array and singly linked list.
Elements in memory are stored randomly, hence elements are accessed sequentially no direct access is
allowed.
Create Doubly Linked List In The List Is Empty:
Create a head and last nodes, allocate the space for the head node and assign some data to head data field.
struct node *head, *last;
head = (struct node *) malloc(sizeof(struct node *));
head->data = data;
Make sure that the previous and next address field of the head node must point to NULL:
head->prev = NULL;
head->next = NULL;
Make the head node as last node:
last = head;
Create Doubly Linked List In The Existing List Contains At Least One Element :
Create a new node:
struct node *newNode;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node(Link the data part)
Make sure that the next address field of the new node must point to NULL:
newNode->next = NULL;
Link the new node previous address field with last Node:
newNode->prev = last; // Link new node with the previous node
Link the last Node next address field with newNode:
last->next = newNode; // Link previous node with the new node:
Move the last Node to newNode:
last = newNode; // Make new node as last/previous node
Traverse(Display) Doubly Linked List From Beginning:
Create a new temporary(temp) node:
struct node *temp;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse to until the last node of the linked list:
while (temp != NULL)
printf("DATA of of the node = %d\n", temp->data);
temp = temp → next; // Move the current pointer to next node in the forward direction
Traverse(Display) Doubly Linked List From End:
Create a new temporary(temp) node:
struct node *temp;
temp is made to point the last node of the list:
temp = last; // temp initialize with last node that stores the address of the last node of the list
Traverse to until the first node of the linked list:
while (temp != NULL)
printf("DATA of of the node = %d\n", temp->data);
temp = temp → prev; // Move the current pointer to next node in the backward direction
Inserting A New node In A Doubly Linked List
There are three different possibilities for inserting a node into a doubly linked list.
1. Insertion at the beginning of the doubly Linked list:
Create a function which insertion at the beginning of doubly linked list.
To defining(create) doubly linked list node structure.
struct node {
int data; //data is the data you want to store in list
struct node * next; // the *next will store location of next node if exists otherwise NULL
struct node * prev; // the *prev will store location of previous node if exists otherwise
NULL
};
Declare a pointer to node type variable to store link of first node of linked list and Create a new node:
struct node *head, * newNode ; // newNode points to the newly created node
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = item;// Assign data value to newly created node
Check whether the list is empty or not. If the condition head == NULL is true. the prev and the next pointer of
the node will point to NULL:
newNode->prev=NULL;
newNode->next = NULL;
Make the new node as the first node of the list:
The condition head == NULL is false and the node will be inserted in beginning. The next pointer of the new
node will point to the existing first node of the list:
newNode ->next = head; // Point to next node which is currently head
Make sure that the previous address field of the head node must point to NULL:
head->prev = NULL; // Previous node of first node is NULL
Link previous address field of head with new node:
head->prev = newNode; // The prev pointer of the existing head will point to the new node being inserted
Move the first Node to newNode:
head = newNode; // Make the new node as head node
2. Insertion at the end of the doubly linked list:
Create a function which insertion at the end of doubly linked list.
Create a new node, temporary(temp) node and declare a pointer to node type variable to store link of first
node of linked list:
struct node *head, *temp, * newNode ;
Allocate the space for the new node and store data into the data part of the node :
newNode = (struct node*)malloc(sizeof(struct node));
newNode->data=item; //Assign data value to newly created node
make the next pointer of the node newNode point to the null as it will be the new last node of the list:
newNode->next = NULL;
Check whether the list is empty or not. If the condition head == NULL is true. the prev and the next pointer of
the node will point to NULL:
newNode->prev=NULL;
Make the new node as the first node of the list:
head= newNode;
The condition head == NULL is false and the node will be inserted as the last node of the list. Initialize the
pointer temp to head:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse to the last node of the linked list:
while(temp->next!=NULL){
temp=temp->next; }// traverse the whole list in order to reach the last node of the list
At the end of the loop, the temp will be pointing to the last node of the list. We need to make the next part of
the temp node point to the new node (newNode):
temp->next = newNode;// Link address part of temp and newNode
make the previous pointer of the node newNode point to the existing last node(temp) of the list:
newNode->prev = temp;
3. Insertion Node At Any Position Of A Doubly Linked List:
Create a function which insertion a node at any point of doubly linked list.
Declere the variable(position) to insert the location of the new node:
int position;
Create a new node and temporary(temp) node:
struct node *newNode, *temp;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node*)malloc(sizeof(struct node));
newNode->data=item;// Assign data value to newly created node(Link the data part)
Insert the location of the new node :
scanf("%d", &position);
Initialize the pointer temp to head:
temp = head; // temp initialize with head that stores the address of the first node of the list
Traverse to N-1th node in the list. Where N is the position to insert:
while(i<position-1 && temp!=NULL)
{
temp = temp->next;
i++;
} // after traversing temp now points to N-1th node
Connect the next address field of newNode with the node pointed by next address field of temp node:
newNode->next = temp->next; // Connect new node with n+1th node
Connect the previous address field of newNode with the temp node:
newNode->prev = temp; // Connect new node with n-1th node
Check if temp->next is not NULL then, connect the previous address field of node pointed by temp.next to
newNode:
temp->next->prev = newNode; //Connect n+1th node with new node
Connect the next address field of temp node to newNode:
temp->next = newNode; // Connect n-1th node with new node
Deleting a Node From A Doubly Linked List
There are three different possibilities for deleting a node from a doubly linked list.
1. Deleting the First Node from a doubly Linked List:
Create a function which deleting the first node from a doubly linked list.
Create a new temporary(temp) node:
struct node *temp;
temp is made to point the first node of the list:
temp = head; // temp initialize with head that stores the address of the first node of the list
Move the head to the second node of the linked list:
head = temp->next;//
make the prev of this new head node point to NULL:
head->prev = NULL; // Remove the link to previous node
Free the memory occupied by the first node:
free(temp); // Delete the first node from memory
2. Deleting the Last Node from a doubly Linked List:
Create a temporary(temp) node and last node:
struct node *temp, *last;
Initialize the pointer temp to last:
temp = last; // temp initialize with last that stores the address of the last node of the list
Move last pointer to 2nd last node:
last = last->prev;
make the last of this new last node point to NULL:
last->next = NULL;// Remove link to of 2nd last node with last node
Free the memory occupied by the last node:
free(temp); // Delete the last node from memory
secondLastNode = temp
temp = temp → next;
At the end of the loop, the temp will be pointing to the last node of the list. The second last node of the list
will point to the next of the temp node(head node):
secondLastNode ->next = temp->next;
Free the memory occupied by the last node:
free(temp); // Delete the last node
Circular Doubly Linked List:
Circular doubly linked list is a more complexed type of data structure in which a node contain pointers to its
previous node as well as the next node.
Circular doubly linked list doesn't contain NULL in any of the node.
The last node of the list contains the address of the first node of the list. The first node of the list also contain
address of the last node in its previous pointer.
Inserting A New node In A Circular Doubly Linked List
There are two different possibilities for inserting a node into a circular doubly linked list.
1. Insertion at the beginning of circular doubly Linked list:
The first step is defining circular doubly linked list node structure.
struct node {
int data; //data is the data you want to store in list
struct node * next; // the *next will store location of next node if exists otherwise NULL
struct node * prev; // the *prev will store location of previous node if exists otherwise NULL
};
Declare a pointer to node type variable to store link of first node of linked list and Create a new node and
temporary(temp)node:
struct node *head, * newNode,*temp ; // newNode points to the newly created node
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node(Link the data part)
Check whether the list is empty or not. The list is empty if the condition head == NULL holds. To make the
head pointer point to newNode node:
head = newNode; //
The prev and the next pointer of the node will point to itself and store data into the data part of the node:
head->prev = head;
head->next = head;
The condition head == NULL become false and the node will be inserted in beginning. Initialize the pointer
temp to head:
temp = head; // temp initialize with head that stores the address of the first node of the list
To traverse the list by using the pointer temp to reach the last node of the list:
while(temp->next != head)
{
temp = temp->next;
}
At the end of the loop, the temp will be pointing to the last node of the list. The last node of the list will
point to the head node, the newNode node of the previous pointer will point to the last(temp) node, the head
node of the previous pointer will point to the newNode node and the newNode node of the next pointer will
point to the head node :
temp->next = newNode ;
newNode -> prev = temp;
head -> prev = newNode;
newNode -> next = head;
Move the first Node to newNode:
head = newNode; // Make the new node as head node
2. Insertion at the end of the Circular doubly linked list:
Declare a pointer to node type variable to store link of first node of linked list and Create a new node and
temporary(temp)node:
struct node *head, * newNode,*temp ; // newNode points to the newly created node
Allocate the space for the new node and store data into the data part of the node :
newNode = (struct node *) malloc(sizeof(struct node *));
newNode → data = data; // Assign data value to newly created node
Check whether the list is empty or not. The list is empty if the condition head == NULL holds. To make the
head pointer point to newNode node:
head = newNode; //
The prev and the next pointer of the node will point to itself and store data into the data part of the node:
head->prev = head;
head->next = head;
The condition head == NULL become false and the node will be inserted in the end of list. Initialize the
pointer temp to head:
temp = head; // temp initialize with head that stores the address of the first node of the list
To traverse the list by using the pointer temp to reach the last node of the list:
while(temp->next != head)
{
temp = temp->next;
}
At the end of the loop, the temp will be pointing to the last node of the list. The first node of the previous
pointer will point to the newNod node, the newNode node of the next pointer will point to the head node, the
last(temp) node of the next pointer will points to the newNode node and the newNode of the previous pointer
will point to the last(temp) node:
head -> prev = newNode;
newNode -> next = head;
temp->next = newNode ;
newNode -> prev = temp;
Deleting a Node From A Circular Doubly Linked List
There are two different possibilities for deleting a node from a circular doubly linked list.
1. Deleting the First Node from a circular doubly Linked List:
Check whether the list is contain empty, one or more nodes. If the condition head == NULL true, to print
underflow on the screen and make exit.
If the list contains single node then, the condition head → next == head will become true. To delete the
entire list:
head = NULL;
Free the memory occupied by the first node(head pointer free):
free(head); // free the pointer head which was pointing to the head node of the list
Create temporary(temp) node:
struct node *temp;
If the list contains more than one node then, the condition temp → next !== head will become true.
Initialize the pointer temp to head:
temp = head; // temp initialize with head that stores the address of the first node of the list
The push operation is used to insert an element into the stack. The new element is added at the topmost
position of the stack.
To insert an element, we first check if top=MAX–1. If the condition is true, an OVERFLOW message is
printed and exit.
If the condition top=MAX–1 is false, increments top to point next empty space:
top++; //
Adds data element to the stack location, where top is pointing:
stack[top] = data; // Push data in stack
2. Pop Operation
The pop operation is used to delete the topmost element from the stack.
To delete the topmost element, we first check if top == -1. If the condition is true, an UNDERFLOW message
is printed and exit.
If the condition top == -1 is false, then delete data element to the stack location, where top is pointing:
stack[top]; //
decrements the value pointed by top on memory space:
top--;
3. Peek Operation
Peek is an operation that returns the value of the topmost element of the stack without deleting it from the
stack.
To peek(display) the topmost element, first check whether the stack is empty top == -1. If the condition is
true, an UNDERFLOW message is printed and exit.
If the condition top == -1 is false, then peek(display) the topmost element, where top is pointing:
stack[top];
Stack implementation using linked list:
In stack Implementation, a stack contains a top pointer. which is “head” of the stack where pushing and
popping items happens at the head of the list.
stack implemented using linked list works for the variable size of data. So, there is no need to fix the size at the
beginning of the implementation.
Stack Operations using Linked List
1. push operation:
First, to define stack node structure:
struct stack
{
int data;
struct stack *next;
} *top;
To insert an element, first check whether the stack is full top=MAX–1 . If the condition is true, an
OVERFLOW message is printed and exit.
If the condition top=MAX–1 is false, then to create a new stack node:
struct stack *newNode;
Allocate the space for a new stack node and store data into the data part of the node :
newNode = (struct stack *) malloc(sizeof(struct stack*));
newNode → data = data; // Assign data value to newly created node
If the list is empty then the item is to be pushed as the start node of the list. A new node make sure that the
address part of the new node points to NULL:
newNode->next=NULL;
To make the top pointer of the stack point to newNode node:
top = newNode; //
If the list is not empty, Link new node with the current stack top most element:
newNode->next = top; //Next element after new node should be current top element
To make the top pointer of the stack point to newNode node:
top = newNode;
2. Pop Operation
Removal of top most element from stack is known as pop operation in stack.
To delete the topmost element of stack, we first check if top == -1. If the condition is true, an UNDERFLOW
message is printed and exit.
If the condition top == -1 is false, then declare temporary(temp) node:
struct stack *temp;
Initialize the pointer temp to top:
temp = top;
Make second element of stack as top element :
top = top->next;
Delete the top most element from memory:
free(temp);
3. Peek Operation
To peek(display) the topmost element, first check whether the stack is empty top == -1. If the condition is
true, an UNDERFLOW message is printed and exit.
If the condition top == -1 is false, then declare temporary(temp) node:
struct stack *temp;
Initialize the pointer temp to top:
temp = top;
To traverse the list of stack by using the pointer temp to reach the top most node of the list:
while(temp->next != NULL)
{
printf("%d--->",temp->data);
temp = temp->next;
}
Application Of Stacks
1. Reversing a List
A list of numbers can be reversed by reading each number from an array starting from the first index and
pushing it on a stack.
Once all the numbers have been read, the numbers can be popped one at a time and then stored in the array
starting from the first index.
Infix, postfix, and prefix notations are three different but equivalent notations of writing algebraic expressions.
In infix notation, the operator is placed in between the operands. Example (A + B) * C
To write expressions using infix notation easy to read for humans, but computers find it difficult to parse as
the computer needs a lot of information to evaluate the expression.
computers work more efficiently with expressions written using prefix and postfix notations.
prefix and postfix notation is easier to parse for a machine.
In postfix notation, the operator is placed after the operands. Example AB+C*
In a prefix notation, the operator is placed before the operands. Example *+ABC
The principal advantage of postfix notation is that parentheses are not used.
Recursion
A recursive function is defined as a function that calls itself to solve a smaller version of its task until a final
call is made.
A recursive function is a function that calls itself until a “base condition” is true, and execution stops.
A recursive function makes use of the system stack to temporarily store the return address and local variables
of the calling function.
Recursion is a technique that breaks a problem into one or more sub-problems that are similar to
the original problem.
Any recursive function can be characterized based on:
whether the function calls itself directly or indirectly (direct or indirect recursion)
whether any operation is pending at each recursive call (tail recursive or not), and
The structure of the calling pattern (linear or tree-recursive).
A function is said to be directly recursive if it explicitly calls itself.
int Func (int n)
{
if (n == 0)
return n;
else
return (Func (n–1));
}
A function is said to be indirectly recursive if it contains a call to another function which ultimately calls it.
Queue is a linear data structure where elements are ordered in special fashion.
A queue is a collection of objects that are added and removed based on the first-in-first-out (FIFO) principle.
It means that the first element added to the queue will be the first one to be removed from the queue.
The elements in a queue are added at one end called the REAR and removed from the other end called the
FRONT.
The basic operations which can be performed on queue:
1. Enqueue() function is used to insert new elements into the end of queue.
2. Dequeue() function is used to remove an element from the front of queue.
3. Peek() function is used to get the front element of queue , without removing it.
4. isFull(): check if queue is full.
5. isEmpty(): check if queue is empty.
Queue can be implemented in two ways, by using either arrays or linked lists.
Queue implementation using array:
In array implementation, the stack is formed by using the array.
All the operations regarding the stack are performed using arrays.
To create queue data structure using array, first define the maximum capacity of queue:
#define max_size 100 // Maximum number of elements that can be stored in a queue[]
int queue[max_size]; // creates a queue of integer,
declare a variable rear Points at the index where the next insertion will be performed and with initialized -1:
unsigned int rear = - 1; // Initially it is indexed to last element of queue
declare a variable front Points at the index where the next deletion will be performed and with initialized -1:
unsigned int front = - 1; // Initially it is indexed to first element of queue
Declare a variable size which keep track of the size of queue and with initialized 0:
unsigned int size = 0;
Operations On A Queue:
1. Enqueue Operation
Enqueue is the process of inserting an element to queue. In queue elements are always inserted at rear of
queue.
To insert an element, we first check if rear == max_size - 1. If the condition is true, an OVERFLOW
message is printed and exit.
If the condition rear == max_size - 1 is false, insert new element on queue. check the queue is empty or not.
If the condition front == -1 && rear == -1 true:
rear++;
front++;
queue[rear] = data;
If the condition front == -1 && rear == -1 false, increments rear to point next empty space:
rear++; //
Increment size of the queue by 1:
size++;
Adds new element at the rear of queue location, where rear is pointing:
queue[rear] = data; // enqueue data in queue
2. Dequeue Operation
Dequeue is the process of removing an element from queue. Elements from queue are always removed from
front of queue.
Before dequeuing, we check if queue is already empty, if size < 0; . If the condition is true, an
UNDERFLOW message is printed and exit.
If the condition size < 0 is false, then delete data element to the queue, where front is pointing and decrement
size of the queue by 1:
size--;
queue[front]; //
Increments the value pointed by front on memory space:
front++;
3. Peek Operation
Peek is an operation that returns either the values of the front or rear elements of the queue without deleting
it from the queue.
To peek(display) the front element, first check whether the queue is empty front == -1 || front > rear. If the
condition is true, an UNDERFLOW message is printed and exit.
If the condition front == -1 || front > rear is false, then peek(display) either the front or rear element :
queue[front];
queue[rear];
Queue implementation using linked list:
There are two basic operations which can be implemented on the linked queues. The operations are Insertion
and Deletion.
Before do any operations on queue, firstly, to define a queue node structure.
struct node {
int data; //data is the data you want to store in queue
struct node * next; // the *next will store location of next node if exists otherwise NULL
};
Declare pointers to node type variables to store the front pointer contains the address of the starting element of
the queue and the rear pointer contains the address of the last element of the queue:
struct node *front, * rear ;
Operations On A Linked List Queue:
1. Enqueue 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.
Create a new node:
struct node *newNode;
Allocate the space for the new node and store data into the data part of the node:
newNode = (struct node *) malloc (sizeof(struct node));
newNode->data = item;// Assign data value to newly created node
Make sure that the newly created node points to nothing:
newNode->next = NULL;
Check whether the queue is empty or not. The queue is empty if the condition front== NULL true. The new
element will be added as the only element of the queue. set front = newNode and rear = newNode:
front = newNode;
rear = newNode;
The next pointer of front and rear pointer both, will point to NULL:
front->next = NULL;
rear->next = NULL;
The condition front == NULL become false. The queue contains more than one element. The next pointer of
rear will point to the new node newNode :
rear->next = newNode;
Move the rear to newNode:
rear = newNode; // Make the new node as rear node
Make sure that the next address field of the rear node must point to NULL:
rear->next = NULL;
2. Dequeue Operation
Before dequeuing, first check whether the queue is empty or not. If the condition front == NULL is true,
an UNDERFLOW message is printed and exit.
If the condition front == NULL is false, then delete the element that is pointed by the pointer front and
declere temporary node pointer temp:
struct node *temp;
Initialize the pointer temp to front:
temp = front; //
Shift the front pointer, point to its next node:
front = front -> next; // shift the next node from front node
Free the memory occupied by the temp node:
free(temp); // Delete the temp node
3. Peek Operation
To peek(display) the front element, first check whether the queue is empty or not. If the condition front
== NULL is true, an UNDERFLOW message is printed and exit.
If the condition front == NULL is false, then peek(display) either the front or rear element. If the condition
temp != NULL is true, to print the front data value :
printf("\n%d\n", temp->data);
temp = temp->next;
Circular Queues
In linear queue, there can't be inserted any more element due to the condition rear == max - 1 becomes true.
However, if we delete some elements at the front end of the queue, we still can not insert any element since
the condition rear = max -1 still holds.
To resolve this problem, to use a circular queue. In the circular queue, the first index comes right after the last
index.
Circular queue will be full only when front = -1 and rear = max-1.
Insertion in Circular queue
To insert an element, we first check if front == -1 && rear == max_size - 1. If the condition is true, the
circular queue is full so an OVERFLOW message is printed and exit.
If the condition front = -1 and rear == max_size - 1 is false, insert new element on queue. check the queue
is empty or not. If the condition front == -1 && rear == -1 true:
rear++;
front++;
queue[rear] = data;
If the condition rear == max_size - 1 && front != -1 is true, set rear to point the first empty space:
rear = -1; //
Adds new element at the rear of queue location, where rear is pointing:
queue[rear] = data; // enqueue data in queue
If the condition front == -1 || rear != max_size - 1 true, Increments rear to point next empty space:
rear++; //
Adds new element at the rear of queue location, where rear is pointing:
queue[rear] = data; // enqueue data in queue
2. Deletion in Circular queue
Before dequeuing, first check whether the queue is empty or not. If the condition front == -1 is true, an
UNDERFLOW message is printed and exit.
If the condition front == rear is true, there is only one element in the queue. set rear and front to point the first
empty space, the queue is deleted completely :
rear = -1;
front = -1;
If the condition front == max_size - 1 true, set front to point the first empty space:
front= -1;
If the condition front == -1 false, Increments the value pointed by front on memory space:
front = front + 1;
Deques
A deque is a list in which the elements can be inserted or deleted at either end.
It is a head-tail linked list because elements can be added to or removed from either the front (head) or the
back (tail) end.
In the computer’s memory, a deque is implemented using either a circular array or a circular doubly linked
list.
In a deque, left and right pointers, which point to either end of the deque.
There are two variants of a double-ended queue:
Input restricted deque: In this dequeue, insertions can be done only at one of the ends, while deletions can be
done from both ends.
Output restricted deque: In this dequeue, deletions can be done only at one of the ends, while insertions can
be done on both ends
A priority queue is a special type of queue in which each element is associated with a priority and is served
according to its priority.
The general rules of processing the elements of a priority queue are:
An element with higher priority is processed before an element with a lower priority.
Two elements with the same priority are processed on a first-come-first-served (FCFS) basis