Unit 2 Notes
Unit 2 Notes
A data structure is basically a group of data elements that are put together under one name, and
which defines a particular way of storing and organizing data in a computer so that it can be
used efficiently.
Data structures are used in almost every program or software system. Some common examples
of data structures are arrays, linked lists, queues, stacks, binary trees, and hash tables. Data
structures are widely applied in the following areas:
• Compiler design
• Operating system
• Statistical analysis package
• DBMS
• Artificial intelligence
• Graphics
Data structures are generally categorized into two classes: Linear and Non Linear data
structures. If the elements of a data structure are stored in a linear or sequential order, then it is
a linear data structure. Examples include arrays, linked lists, stacks, and queues. Linear data
structures can be represented in memory in two different ways. One way is to have to a linear
relationship between elements by means of sequential memory locations. The other way is to
have a linear relationship between elements by means of links. However, if the elements of a
data structure are not stored in a sequential order, then it is a non-linear data structure. The
relationship of adjacency is not maintained between elements of a non-linear data structure.
Examples include trees and graphs.
Figure 1: Types of data Structures
Linear data structures can be traversed Non-linear data structures are not easy to
completely in a single run. traverse and needs multiple runs to be
traversed completely.
Linear data structures are not very memory Non-linear data structures uses memory
friendly and are not utilizing memory very efficiently.
efficiently.
Time complexity of linear data structure often Time complexity of non-linear data
increases with increase in size. structure often remain with increase in size.
An abstract data type (ADT) is the way we look at a data structure, focusing on what it does
and ignoring how it does its job. For example, stacks and queues are perfect examples of an
ADT. We can implement both these ADTs using an array or a linked list. This demonstrates
the ‘abstract’ nature of stacks and queues.
LIST ADT:
List is a linear data structures which consists of sequential collection of elements of same
data type. List can be implemented using arrays and Linked List
Basic Operations
• Creation
• Insert
• Delete
• Find/Search
• Display/Traversal
Creation:
# define maxsize 10
int lst[maxsize];
int size=0
The variable maxsize denotes the size of the array and size represents the number of elements
in the List. Since the list is empty, size is 0.
Insert Operation
Inserting an element into list requires the position to be inserted. To insert an element at
intermediate position requires movement of element after the position to be inserted by one
position to its right. Insertion into the list cannot be done it the list is already full.
void insert(int pos, int val)
{
if(size<maxsize-1)
{
if( ( pos>=0) && (pos<=size ) )
{
for (int k=size-1;k>=pos;k--)
lst[k+1]=lst[k];
lst[pos]= val;
size++;
printf(“ %d has been inserted”, val);
}
else
printf(“\n Invalid position”);
}
else
printf(“\n List is full”);
}
Delete Operation:
Deletion of an element from the list requires to find the position of the element to be deleted.
Deleting an element at intermediate position requires movement of element after deletion to be
moved by one position to its left.
void remove(int pos)
{
if(pos>=0 && pos<size)
{
printf(“%d is removed", lst[pos]);
for(int k=pos;k<size;k++)
{
lst[k]=lst[k+1];
}
size--;
}
else
printf(“\n Element Cannot be Removed”);
}
Search/Find Operation:
Searching an element in list is based on linear search. It sequentially checks each element of
the list until a match is found or the whole list has been searched
Traversing the element is done by iterating from first to last element directly by using the index
of the list
void display()
{
printf(“\n List Elements are..”);
for(int i=0;i<size;i++)
printf(“\n %d”,lst[i]);
}
Disadvantages:
LINKED LIST
A linked list, in simple terms, is a linear collection of data elements. These data elements are
called nodes. Linked list is a data structure which in turn can be used to implement other data
structures. Thus, it acts as a building block to implement data structures such as stacks, queues,
and their variations. A linked list can be perceived as a train or a sequence of nodes in which
each node contains one or more data fields and a pointer to the next node. Every node has two
parts: Data and a pointer (link)
Types of Linked List
Every node has a data part and a pointer that links to the next node
struct node
{
int data;
struct node *next;
}*head=NULL;
Basic Operations:
• Insertion
• Deletion
• Traverse/Display
• Search/Find
Insert Operation
Insertion is process of adding elements into the list. Based on the position to be inserted
insertion is classified as:
• Insert at First
• Insert at Last
• Insert after a specific element
Insert at First
Inserting an element at beginning requires creation of new node and changing the pointer
assignment of head pointer
Before Insertion
After Inserting 7
Inserting an element at last requires creation of new node, traversing the list to the last node
and changing the pointer assignment of last node to point to the new node.
Before Insertion
n1->next=NULL;
temp=head;
while(temp->next!=NULL)
temp=temp->next;
temp->next=n1;
The pointer temp starts from the first element and iterates through every element to find
the last element and the newnode n1 is assigned as the next node of the last node temp.
Inserting an element after a specific element needs to find the element, creation of new node
and changing the pointer assignment accordingly.
Before Insertion
After Inserting 75
}
In the above code, the pointer temp searches for the specified element from the starting
of the list. On finding the specified element as temp, the next pointer of temp and n1 is
changed accordingly.
Deletion
Deletion of a node in singly linked list needs to find the element to be deleted and tracking its
previous element in the list and changing the pointer of the previous node accordingly.
Before Deletion
After Deleting 50
Searching an element in list is based on linear search. It sequentially checks each element of
the list until a match is found or the whole list has been searched.
void search(int val)
{
struct node *temp;
temp=head;
while(temp!=NULL)
{
if(temp->data==val)
{
printf("\nElement found in the list");
return;
}
else
temp=temp->next;
}
printf("\nElement not found");
}
Display/Traverse
Traversing the element is done by iterating from first to last element directly by using the head
pointer.
void display()
{
struct node *temp;
temp=head;
printf("\nThe elements of linked list are....");
while(temp!=NULL)
{
printf("\%d->",temp->data);
temp=temp->next;
}
}
Basic Operations:
• Insertion
• Deletion
• Traverse/Display
• Search/Find
Structure of Node
Every node has a data part, a pointer that links to the next node and a pointer that refers to the
previous node.
struct node
int data;
}*head=NULL;
Insert Operation
Insertion is process of adding elements into the list. Based on the position to be inserted
insertion is classified as:
• Insert at First
• Insert at Last
• Insert after a specific element
Insert at First
Inserting an element at beginning requires creation of new node and changing the pointer
assignment of head pointer
Before Insertion
After Inserting 5
Inserting an element at last requires creation of new node, traversing the list to the last node
and changing the next pointer assignment of last node to point to the new node, prev pointer
of new node to point to the existing last node
Before Insertion
After Inserting 50
Inserting an element after a specific element needs to find the element, creation of new node
and changing the next and prev pointer assignment accordingly.
Before Insertion
Inserting 25 after 30
temp=head;
while(temp!=NULL)
if(temp->data==after)
n1->next=temp->next;
n1->prev=temp;
aft=temp->next;
aft->prev=n1;
temp->next=n1;
return;
else
temp=temp->next;
In the above code, the pointer temp searches for the specified element from the starting
of the list. On finding the specified element as temp, the next pointer of temp and n1 is
changed accordingly. The prev pointers of n1 and after is assigned accordingly where
after is the next node of specified node.
Delete Operation
Deleting an element in the list requires finding the element, changing the next and prev
pointer of its adjacent nodes accordingly.
Before deletion
After deleting 30
Searching an element in list is based on linear search. It sequentially checks each element of
the list until a match is found or the whole list has been searched
Traversing the element is done by iterating from first to last element directly by using the
head pointer.
void display()
{
struct node *temp;
temp=head;
printf(“List Elements are....”);
while(temp!=NULL)
{
printf(“%d->”,temp->data);
temp=temp->next;
}
}
Applications of linked list:
A linked list is a linear data structure, in which the elements are not stored at contiguous
memory locations. The elements in a linked list are linked using pointers as shown in the
below image:
Circular singly linked list: In a circular Singly linked list, the last node of the list contains a
pointer to the first node of the list. We traverse the circular singly linked list until we reach the
same node where we started. The circular singly linked list has no beginning or end. No null
value is present in the next part of any of the nodes.
Basic Operations:
• Insertion
• Deletion
• Traverse/Display
• Search/Find
Representation of node
struct node
{
int data;
struct node *next;
}*head=NULL;
Insert Operation
Insertion is process of adding elements into the list. Based on the position to be inserted
insertion is classified as:
• Insert at First
• Insert at Last
• Insert after a specific element
Insert at First
Inserting an element at beginning of circular linked list requires creation of new node and
changing the pointer assignment of head pointer to the newnode n1and the next pointer of last
node to n1.
Before Insertion
After Inserting 40
Inserting an element at last requires creation of new node, traversing the list to the last node
and changing the pointer assignment of last node to point to the new node. The next pointer of
newnode refers to the first node.
Before Insertion
After Inserting 40
void insertlast(int val)
{
struct node *n1= (struct node *)malloc(sizeof(struct node));
struct node *temp;
n1->data=val;
if(head==NULL)
{
n1->next=n1;
head=n1;
}
else
{
temp=head;
while(temp->next!=head)
temp=temp->next;
temp->next=n1;
n1->next=head;
}
}
If the list is empty, the newnode n1 is inserted as the first node and next pointer refers to itself.
If the list is not empty, the next pointer of last is changed to refer to newnode n1 and the next
pointer of n1 refers to the first node.
Insert after a specific element
Inserting an element after a specific element needs to find the element, creation of new node
and changing the pointer assignment accordingly.
Before Insertion
Before Deletion
After deleting 30
void remov(int val)
{
struct node*temp, *before, *last;
temp=head;
if(temp->data==val)
{
if(temp->next==head)
{
free(temp);
head=NULL;
return;
}
else
{
last=head->next;
while(last->next!=head)
last=last->next;
head=head->next;
last->next=head;
free(temp);
return;
}
}
else
{
temp=head->next;
before=head;
while(temp!=head)
{
if(temp->data==val)
{
before->next=temp->next;
free(temp);
return;
}
else
{
temp=temp->next;
before=before->next;
}
}
}
}
If the element to be deleted is the first node, the next pointer of the last node should be
updated. If the intermediate element is deleted the next pointer of previous node is updated
with the address of the nest node after specified node.
Find/Search Operation
Searching an element in circular linked list is based on linear search. It sequentially checks
each element of the list until a match is found or the whole list has been searched.
void search( int val)
{
struct node *temp;
temp=head;
do
{
if(temp->data==val)
{
printf("\nElement found in the circular list");
return;
}
else
temp=temp->next;
}while(temp!=head);
printf("\nElement not found in the circular list");
}
Display/Traverse
Traversing the element is done by iterating from first to last element directly by using the head
pointer.
void display()
{
struct node * temp;
temp=head;
printf("\n Elements in the circular liked list are...");
do
{
printf("%d->",temp->data);
temp=temp->next;
}while(temp!=head);
}
POLYNOMIAL MANIPULATION
Polynomial manipulations are one of the most important applications of linked lists.
Polynomials are an important part of mathematics not inherently supported as a data type by
most languages. A polynomial is a collection of different terms, each comprising coefficients,
and exponents. It can be represented using a linked list. This representation makes polynomial
manipulation efficient.
While representing a polynomial using a linked list, each polynomial term represents a node in
the linked list. To get better efficiency in processing, we assume that the term of every
polynomial is stored within the linked list in the order of decreasing exponents. Also, no two
terms have the same exponent, and no term has a zero coefficient and without coefficients. The
coefficient takes a value of 1.
o The first part contains the value of the coefficient of the term.
o The second part contains the value of the exponent.
o The third part, LINK points to the next term (next node).
The structure of a node of a linked list that represents a polynomial is shown below:
struct poly
int coeff;
int power;
};
Consider a polynomial P(x) = 7x2 + 15x3 - 2 x2 + 9. Here 7, 15, -2, and 9 are the coefficients,
and 4,3,2,0 are the exponents of the terms in the polynomial. On representing this polynomial
using a linked list, we have
Observe that the number of nodes equals the number of terms in the polynomial. So we have 4
nodes. Moreover, the terms are stored to decrease exponents in the linked list. Such
representation of polynomial using linked lists makes the operations like subtraction, addition,
multiplication, etc., on polynomial very easy.
Creation of polynomial:
Addition of Polynomials:
To add two polynomials, we traverse the list P and Q. We take corresponding terms of the list
P and Q and compare their exponents. If the two exponents are equal, the coefficients are added
to create a new coefficient. If the new coefficient is equal to 0, then the term is dropped, and if
it is not zero, it is inserted at the end of the new linked list containing the resulting polynomial.
If one of the exponents is larger than the other, the corresponding term is immediately placed
into the new linked list, and the term with the smaller exponent is held to be compared with the
next term from the other list. If one list ends before the other, the rest of the terms of the longer
list is inserted at the end of the new linked list containing the resulting polynomial.
Example: 1
Let us consider an example an example to show how the addition of two polynomials is
performed,
Q (x) = 5x3 + 4 x2 - 5
These polynomials are represented using a linked list in order of decreasing exponents as
follows:
Creation of Polynomial
To generate a new linked list for the resulting polynomials that is formed on the addition of
given polynomials P(x) and Q(x), we perform the following steps,
1. Traverse the two lists P and Q and examine all the nodes.
2. We compare the exponents of the corresponding terms of two polynomials. The first
term of polynomials P and Q contain exponents 4 and 3, respectively. Since the
exponent of the first term of the polynomial P is greater than the other polynomial Q,
the term having a larger exponent is inserted into the new list. The new list initially
looks as shown below:
3. We then compare the exponent of the next term of the list P with the exponents of the
present term of list Q. Since the two exponents are equal, so their coefficients are added
and appended to the new list as follows:
4. Then we move to the next term of P and Q lists and compare their exponents. Since
exponents of both these terms are equal and after addition of their coefficients, we get
0, so the term is dropped, and no node is appended to the new list after this,
5. Moving to the next term of the two lists, P and Q, we find that the corresponding terms
have the same exponents equal to 0. We add their coefficients and append them to the
new list for the resulting polynomial as shown below:
Example: 2
10x2 + 26x, here 10 and 26 are coefficients and 2, 1 is its exponential value.
Display of polynomial
A sparse matrix in data structures is a matrix where most of the elements are zero. It's
characterized by a significantly higher proportion of zero values compared to non-zero
values. Representing a sparse matrix efficiently is crucial, as storing all zero elements would
be wasteful in terms of memory and computation.
• Storage: There are lesser non-zero elements than zeros and thus lesser memory can be
used to store only those elements.
• Computing time: Computing time can be saved by logically designing a data structure
traversing only non-zero elements.
Sparse Matrix Representations can be done in many way,s following are two common
representations:
1. Array representation
2D array is used to represent a sparse matrix in which there are three rows named as
In linked list, each node has four fields. These four fields are defined as:
• Row: Index of row, where non-zero element is located