Unit 2 Notes
Unit 2 Notes
Unit 2 Notes
Operations on List ADT – Create, Insert, Search, Delete, Display elements; Implementation of List ADT–
Array, Cursor based and Linked; Types – Singly, Doubly, Circular; Applications - Sparse Matrix,
Polynomial Arithmetic, Joseph Problem
Insertion and Deletion operation are expensive as it requires more data movement
Find and Printlist operations takes constant time.
Even if the array is dynamically allocated, an estimate of the maximum size of the list is
required which considerably wastes the memory space.
Linked list consists of series of nodes. Each node contains the element and a pointer to its
successor node. The pointer of the last node points to NULL.
Insertion and deletion operations are easily performed using linked list.
ARRAY IMPLEMENTATION
In an array implementation, elements are stored in contiguous array positions as shown in thebelow
figure.
1. 1-D representation
2. 2-D representation
3. Multi-dimensional representation
1D ARRAY REPRESENTATION
In 1D array representation, the elements will be mapped into a single dimensional contiguous memory location. Let x be an
array with elements [a, b, c, d]. The below figure shows how thearray elements will be stored in memory.
A 2D array ‘a’ of size 3 X 4 will be declared as follows: int a[3][4]. The tabular representation of the
2D array ‘a’ is shown as follows:
The method of storing elements in a 2D array is called as array-of-arrays representation. This will
require 4 1D arrays of size 3,4,4,4 to store the array ‘a’. The below figure shows how elements of ‘a’
of size 3 X 4 will be stored in a memory.
APPLICATIONS ON ARRAYS
An Arrays in data Structure is a container which can hold a fixed number of items andthese
items should be of the same type.
Arrays are used to implement mathematical vectors and matrices, as well as other kinds of
rectangular tables. Many databases, small and large, consist of one-dimensional arrays whose
elements are records.
Arrays are used to implement other data structures, such as lists, heaps, hash tables,
deques, queues and stacks.
One or more large arrays are sometimes used to emulate in-program dynamic memory
allocation, particularly memory pool allocation. Historically, this has sometimes been the only
way to allocate "dynamic memory" portably.
Arrays can be used to determine partial or complete control flow in programs, as a compact
alternative to (otherwise repetitive) multiple “if” statements. They are known
in this context as control tables and are used in conjunction with a purpose-built interpreter
whose control flow is altered according to values contained in the array. The array may contain
subroutine pointers (or relative subroutine numbers that can be acted upon by SWITCH
statements) that direct the path of the execution.
IMPLEMENTATION OF ARRAYS – INSERTION AND DELETION
//To Insert An Element In An Array
#include<stdio.h>
int insertElement(int arr[], int elements, int keyToBeInserted, int size)
{
if (elements >= size)
return elements;
arr[elements] = keyToBeInserted;
return (elements + 1);
}
int main()
{
int array[20] = { 23,35,45,76,34,92 };
int size = sizeof(array) / sizeof(array[0]);int
elements = 6;
int i, keyToBeInserted = 65;
printf("\n Before Insertion: ");for
(i = 0; i < elements; i++)
{
printf("%d ", array[i]);
}
elements = insertElement(array, elements, keyToBeInserted, size);
printf("\n After Insertion: ");
for (i = 0; i < elements; i++)
{
printf("%d ",array[i]);
}
return 0;
}
Output:
Before Insertion: 23 35 45 76 34 92
After Insertion: 23 35 45 76 34 92 65
Explanation:
Main function call the insert function to insert an element in an array by passing the parameters arr[] =
array, elements = number of elements present in the array and keyToBeInserted = element to be
inserted in the array with the size of the array. It checks if the maximum space of the array is already
full and return the elements. If not then the element is inserted at the last index and the new array size is
returned.
//To Delete An Element In An Array
#include<stdio.h>
int deleteElement(int array[], int size, int keyToBeDeleted)
{
int pos = findElement(array, size, keyToBeDeleted); int i;
if (pos == - 1)
{
printf("Element not found");
return size;
}
for (i = pos; i < size - 1; i++)
{
array[i] = array[i + 1];
return size - 1;
}
}
int findElement(int array[], int size, int keyToBeDeleted)
{
int i;
for (i = 0; i < size; i++)
if (array[i] == keyToBeDeleted)
return i;
else return
- 1;
}
int main()
{
int array[] = { 31, 27, 3, 54, 67, 32 };
int size = sizeof(array) / sizeof(array[0]);int
i, keyToBeDeleted = 67;
printf("n Before Deletion: ");
for (i = 0; i < size; i++)
printf("%d ", array[i]);
deleteElement(array, size, keyToBeDeleted);
printf("n After Deletion: ");
for (i = 0; i < size; i++)
printf("%d ",array[i]);
return 0;
}
Output:
Before Deletion: 31 27 3 54 67 32
After Insertion: 31 27 3 54 32
Explanation:
Main function call the delete function to delete an element by passing the parameters array[] is the array
from which element needs to be deleted ,size of the array and keyToBeDeleted is the element to be
deleted from the array. If element is not found then it prints Element not found. Else it deletes the
element & moves rest of the element by one position.
//To Search an Element in an Array
#include<stdio.h>
int findElement(int array[], int size, int keyToBeSearched)
{
int i;
for (i = 0; i < size; i++)
if (array[i] == keyToBeSearched)
return i;
else
return - 1;
}
int main()
{
int array[] = { 41, 29, 32, 54, 19, 3};
int size = sizeof(array) / sizeof(array[0]);int
keyToBeSearched = 67;
int pos = findElement(array, size, keyToBeSearched);
if(pos==-1)
{
printf("n Element %d not found", keyToBeSearched);
}
else
{
printf("n Position of %d: %d", keyToBeSearched ,pos+1);
}
return 0;
}
Output:
Position of 19:5
EXPLANATION
Main function call sub function to search the element in the given array by passing the parameters the
array from which element needs to be deleted, size of the array and keyToFind is the element to be
search from the array. Running a for loop for Finding & returning the position of the element.
ARRAY IMPLEMENATATION OF A LINKED LIST:
Approach regarding create linked list from a given array
The approach involves traversing the array from one end to the other. For each element encountered during the traversal, a new
node is created with that element’s value, and then the node is inserted into the linked list.
1. Start with an empty linked list (initialize the head pointer as null).
2. Traverse the array from the beginning to the end.
3. For each element in the array:
4. Create a new node with the current element’s value.
5. If the linked list is empty (head is null), set the new node as the head.
6. Otherwise, set the next pointer of the last node in the linked list to point to the new node.
7. Update the last node pointer to the newly created node.
8. After processing all elements in the array, the linked list is constructed.
straightforward loop, which we leave as an exercise. To perform an malloc, the first element (after the
header) is removed from the freelist.
To perform a free, we place the cell at the front of the freelist. The below routine shows the cursor
implementation of malloc and free.
Notice that if there is no space available, our routine does the correct thing by setting p = 0. This
indicates that there are no more cells left, and also makes the second line of cursor_new a nonoperation
(no-op). Given this, the cursor implementation of linked lists is straightforward. For consistency, we
will implement our lists with a header node.
An example of cursor implementation of linked list is shown below. In the figure, if the value of L is 5
and the value of M is 3, then L represents the list a, b, e, and M represents the list c, d, f.
Example of a cursor implementation of linked lists
LINKED LIST
Linked list consists of series of connected nodes. Each node contains the element (a piece of data) and
a pointer to its successor node. The pointer of the last node points to NULL. A linked list can grow or
shrink in size as the program runs. A linked list representation requires no estimate of the maximum
size of the list. Space wastage is reduced in linked list representation.
The below figure shows a node structure with data and a pointer to the next node and a list of
elements (A1, A2, A3, A4, A5) stored using linked list representation. Insertion and deletion
operations are easily performed using linked list, when compared to using arrays.
Each node points in a singly linked list has a successor. There will be NULL value in the next pointer
field of the last node in the list
2. Doubly Linked List
In a doubly linked list, each node points to not only successor but the predecessor also.There
are two NULL: at the first and last nodes in the list. Advantage of having a doubly linked list is that in
given a list, it is easy to visit its predecessor. It will be convenient to traverse listsbackwards
In a circular linked list, The last node points to the first node of the list.
A node in a linked list is usually of structure data type. The declaration of the node structure using
pointers is as follows:
– Insert an element.
– Delete an element.
INSERTING A NEW NODE
In a linked list, inserting a new node has the following possible cases.
• Each node contains a value and a link to its successor (the last node has no successor)
• The header points to the first node in the list (or contains the null link if the list is empty)
• The entry point into a linked list is called the head of the list.
• It should be noted that head is not a separate node, but the reference to the first node.
head=newNode; head-
>next = NULL;
//If already elements are there in the list
newNode->next = head;
head=newNode;
Initially, the linked list has elements 20 and 30. Node with data 20 is the first node, whose address is
stored in the head. Now to insert a new node with data 10, copy the address of node with data 20 from
head and store in new nodes next pointer. Then make the head point to the new node.
INSERTING AT END OF THE LIST
Steps involved in inserting a new node at the end in the list are as follows: Step 1:
Create a newNode with given value and newNode → next as NULL.Step 2: Check
whether list is Empty (head == NULL).
2. If the Node pointer does not points to NULL then move the Node pointer to the nextnode
until it points to NULL
nodePtr=nodePtr->next;
3. When it reaches NULL append the newNode at the last
nodePtr ->next=newNode;
newNode->next=NULL;
Routine To Insert An Element At The End
INSERTING A NEW NODE IN THE MIDDLE
Steps involved in inserting a new node in the middle of the list are as follows:
Step 1: Create a newNode with given value.
Step 2: Check whether list is Empty (head == NULL)
Step 3: If it is Empty then, set newNode → next = NULL and head = newNode. Step 4: If
it is Not Empty then, define a node pointer temp and initialize with head.
Step 5: Keep moving the temp to its next node until it reaches to the node after which we want to
insert the newNode (until temp → data is equal to location, here location is the node value after
which we want to insert the newNode).
Step 6: Every time check whether temp is reached to last node or not. If it is reached to last node
then display 'Given node is not found in the list!!! Insertion not possible!!!' and terminate the
function. Otherwise move the temp to next node.
Step 7: Finally, Set 'newNode → next = temp → next' and 'temp → next = newNode'
1. Use a Node Pointer to trace to the current position and to store the value of the next
address.
3. The New Node Pointer find the next node to insert the node
previousNode->next=newNode;
newnode->next=nodePtr;
Routine to Insert a New Node in Between
DELETING A NODE
In a linked list, deleting a node has the following possible cases.
1. Use a Node Pointer to trace to the current position and also to store the value of the nextaddress
2. Use a Previous Node Pointer to trace to the current position
temp2=temp1;
temp1=temp1->next;
Circular linked list is a linked list where all nodes are connected to form a circle. There is no NULL at
the end. A circular linked list can be a singly circular linked list or doubly circular linked list.
head = new;
new->next=head;
Step 4 - If it is Not Empty then, define a Node pointer 'temp' and initialize with 'head'.
Step 5 - Keep moving the 'temp' to its next node until it reaches to the last node (until'temp
→ next == head').
Step 6 - Set 'newNode → next =head', 'head = newNode' and 'temp → next = head'.
Step 3 - If it is Empty then, set head = newNode and newNode → next = head. Step 4 - If
it is Not Empty then, define a node pointer temp and initialize with head.
Step 5 - Keep moving the temp to its next node until it reaches to the last node in the list(until
temp → next == head).
Step 3 - If it is Empty then, set head = newNode and newNode → next = head. Step 4 - If
it is Not Empty then, define a node pointer temp and initialize with head.
Step 5 - Keep moving the temp to its next node until it reaches to the node after which we want to
insert the newNode (until temp1 → data is equal to location, here location is the node value after
which we want to insert the newNode).
Step 6 - Every time check whether temp is reached to the last node or not. If it is reached to last
node then display 'Given node is not found in the list!!! Insertion not possible!!!' and
terminate the function. Otherwise move the temp to next node.
Step 7 - If temp is reached to the exact node after which we want to insert the newNode then
check whether it is last node (temp → next == head).
Step 8 - If temp is last node then set temp → next = newNode and newNode → next =
head.
Step 8 - If temp is not last node then set newNode → next = temp → next and temp → next =
newNode.
In a circular linked list, the deletion operation can be performed in three ways those are as follows...
Step 5 - If it is reached to the last node then display 'Given node not found in the list! Deletion
not possible!!!'. And terminate the function.
Step 6 - If it is reached to the exact node which we want to delete, then check whether list is
having only one node (temp1 → next == head)
Step 7 - If list has only one node and that is the node to be deleted then set head
= NULL and delete temp1 (free(temp1)).
Step 8 - If list contains multiple nodes then check whether temp1 is the first node in the list
(temp1 == head).
Step 9 - If temp1 is the first node then set temp2 = head and keep moving temp2 to its next node
until temp2 reaches to the last node. Then set head = head → next, temp2 → next = head and
delete temp1.
Step 10 - If temp1 is not first node then check whether it is last node in the list (temp1 → next ==
head).
Step 1 1- If temp1 is last node then set temp2 → next = head and delete
temp1 (free(temp1)).
Step 12 - If temp1 is not first node and not last node then set temp2 → next = temp1 → next
and delete temp1 (free(temp1)).
1. Node Creation
2. Insertion at beginning
3. Insertion at end
4. Insertion after specified node
5. Deletion at beginning
6. Deletion at end
7. Deletion of the node having given data
8. Searching
9. Traversing
NODE CREATION
struct node
{
struct node *left;
int data;
struct node *right;
};
struct node *head;
INSERTION AT BEGINNING
void insert_at_begin()
{
struct node *tempptr;
int item;
tempptr = (struct node *)malloc(sizeof(struct node));
printf("\nEnter Item value");
scanf("%d",&item);
if(head==NULL)
{
tempptr->right = NULL;
tempptr->left=NULL;
tempptr->data=item;
head=tempptr;
}
else
{
tempptr->data=item;
tempptr->left=NULL;
tempptr->right = head;
head->left=tempptr;
head=tempptr;
} printf("\nInsertion
completed\n");
}
INSERTION AT END
void insert_at_last()
{
struct node *tempptr,*temp;
int item;
tempptr = (struct node *) malloc(sizeof(struct node));
printf("\nEnter value");
scanf("%d",&item);
tempptr->data=item;
if(head == NULL)
{
tempptr->right = NULL;
tempptr->left = NULL;
head = tempptr;
}
else
{
temp = head;
while(temp->right!=NULL)
{
temp = temp->right;
}
temp->right = tempptr;
tempptr ->left=temp;
tempptr->right = NULL;
}
}
printf("\n insertion completed \n");
}
temp=head;
printf("Enter the location");
scanf("%d",&loc);
for(i=0;i<loc;i++)
{
temp = temp->right;
if(temp == NULL)
{
printf("\n There are less than %d elements", loc);
return;
}
}
printf("Enter data");
scanf("%d",&item);
tempptr->data = item;
tempptr->right = temp->right;
tempptr -> left = temp;
temp->right = tempptr; temp-
>right->left=tempptr;
printf("\n insertion completed \n");
DELETION AT BEGINNING
void delete_at_begin()
{
struct node *tempptr;
if(head == NULL)
{
printf("\n UNDERFLOW");
}
else if(head->right == NULL)
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{
tempptr = head; head
= head -> right;
head -> left = NULL;
free(tempptr); printf("\nnode
deleted\n");
}
DELETION AT END
void delete_at_last()
{
struct node *tempptr;
if(head == NULL)
{
printf("\n UNDERFLOW");
}
else if(head->right == NULL)
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{
tempptr = head;
if(tempptr->right != NULL)
{
tempptr = tempptr -> right;
}
tempptr -> left -> right = NULL;
free(tempptr);
printf("\nnode deleted\n");
}
}
DISPLAY_FULL_LIST LIST
void display_full_list()
{
struct node *tempptr; printf("\n
printing values...\n");tempptr =
head;
while(tempptr != NULL)
{
printf("%d\n",tempptr->data);
tempptr=tempptr->right;
}
}
MAIN FUNCTION:
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head; void
insert_at_begin(); void
insert_at_last();
void insert_after_spcific_node();
void delete_at_begin();
void delete_at_last();
void deletion_specified();
void display_full_list();
void search();
void main ()
{
int option =0;
while(option != 9)
{
printf("\nChoose option from below menu\n");
printf("\n1.Insert begining\n 2.Insert last\n 3.Insert any random location \n 4.Deletethe first
node \n 5.Delete the last node\n6.Delete the node after the given data\n7.Search\n8.Show\n9.Exit\n");
printf("\nEnter your option?\n");
scanf("\n%d",&option);
switch(option)
{
case 1:
insert_at_begin();
break;
case 2:
insert_at_last();
break;
case 3:
insert_after_specific_node();
break;
case 4:
delete_at_begin();
break;
case 5:
delete_at_last();
break;
case 6:
deletion_specified();
break;
case 7:
search();
break;
case 8:
display_full_list();
break;
case 9:
exit(0);
break;
default:
printf("Please enter valid option..");
}
}
}
OUTPUT:
Choose option from below menu
1.Insert begining
2. Insert last
3. Insert any random location
4.Delete the first node
5. Delete the last node
6.Delete the node after the given data
7.Search
8.Show
9.Exit
Enter your option?1
Enter Item value 10
Insertion completed.
Choose option from below menu
1.Insert begining
2. Insert last
3. Insert any random location
4.Delete the first node
5. Delete the last node
6.Delete the node after the given data
7.Search
8.Show
9.Exit
Enter your option?
1
Enter Item value 20
Insertion completed.
Choose option from below menu
1.Insert begining
2. Insert last
3. Insert any random location
4.Delete the first node
5. Delete the last node
6.Delete the node after the given data
7.Search
8.Show
9.Exit
Enter your option?
8
Printing values…
20
10
Explanation:
This program having many functions each performing one operation in doubly linked list. When the
program is executed, list of options or operation that we can perform in the linked list displayed. Each
option is associated with one function which is called by the switch case based on the user input.
When the input 1 is given after executing program, the function insert_at_begin(); is called. It creating
the new node with the user entered data 10. Again new node is inserted at the beginning using the
same function with value 20. Right now the doubly list having the two node. The first node data is 20
and second is 10. We can display the list by calling display full list function through option 8. Then the
first node is deleted from the list by giving option 4 that calling deleting_at_begin function. After this
operation, the list would have only one value that is 10. Likewise, all the operation in the doubly linked
can be performed using above writing function.
MULTI-DIMENSIONAL SPARSE MATRIX
A matrix is a two-dimensional data object made of m rows and n columns. Generally, a matrix is
represented to have m X n values. When the value of m is equal to n, then it is called as a square
matrix.
There may be a situation in which a matrix may contains a greater number of ‘0’ values
(elements) than NON-ZERO values. Such matrix is known as sparse matrix. But when a sparse
matrix is represented with 2-dimensional array with all ZERO and non-ZERO values, lot of space
is wasted to represent that matrix.
For example, consider a matrix of size 200 X 200 containing only 10 non-zero elements. In this
matrix, only 10 spaces are filled with non-zero values and remaining spaces of the matrix are
filled with zero values. That means, totally we allocate 200 X 200 X 2 = 80000 bytes of space to
store this integer matrix. And to access these 10 non-zero elements we have to make scanning for
80000 times. This results in an increased time and space complexity. An example sparse matrix is
given below:
For example, consider a matrix of size 5 X 6 containing 6 number of non-zero values. This matrix can
be represented as shown in the image.
In above example matrix, there are only 6 non-zero elements (those are 9, 8, 4, 2, 5 & 2) and matrix
size is 5 X 6. We represent this matrix as shown in the above image. Here the first row in the right-side
table is filled with values 5, 6 & 6 which indicates that it is a sparse matrix with 5 rows, 6 columns &
6 non-zero values. The second row is filled with 0, 4, & 9 which indicates the non-zero value 9 is at
the 0th-row 4th column in the Sparse matrix. In the same way, the remaining non-zero values also
follow a similar pattern.
LINKED LIST REPRESENTATION
A sparse matrix could be represented using a linked list data structure also. In linked list, each node
has four fields. These four fields are defined as:
POLYNOMIAL ARITHMETIC
The manipulation of symbolic polynomials, has a classic example of list processing. In general,
we want to represent the polynomial:
Where the ai are nonzero coefficients and the ei are nonnegative integer exponentssuch that
em-1 > em-2 > … > e1 > e0 ≧ 0
We will represent each term as a node containing coefficient and exponent fields, as well asa
pointer to the next term. A node structure for a polynomial is shown below.
Assuming that the coefficients are integers, the node structure will be declared as follows:
struct link
{
int coeff;
int pow;
struct link *next;
};
Consider the polynomials a 3x14 2x8 1 and b 8x14 3x10 10x6 The
. linked
list representation of the polynomials a and b are shown below.
Routine to Create a Polynomial Linked List
POLYNOMIAL ADDITION
• To add two polynomials, we examine their terms starting at the nodes pointed to by a and
b.
• If the exponents of the two terms are equal
• add the two coefficients and create a new term for the result.
• If the exponent of the current term in a is less than b
• create a duplicate term of b and attach this term to the result, called d
• advance the pointer to the next term in b.
• We take a similar action on a if a->expon > b->expon.
The figure shows generating the first three term of d = a+b below.
From the above figure it is observed that when the exponents of a and b are equal, coefficients of a and
b are added in the new polynomial d. Else if the exponent of a is bigger than exponent of b, link the
corresponding node of a to d and vice versa. Routine to create a linked list for a polynomial is give
below.
JOSEPH PROBLEM
There are n people standing in a circle waiting to be executed. The counting out begins at some point in
the circle and proceeds around the circle in a fixed direction. In each step, a certain number of people
are skipped and the next person is executed. The elimination proceeds around the circle (which is
becoming smaller and smaller as the executed people are removed), until only the last person remains,
who is given freedom. Given the total number of persons n and a number m which indicates that m-1
persons are skipped and m-th person is killed in circle. The task is to choose the place in the initial
circle so that you are the last one remaining and so survive.
Examples:
ROUTINE FOR JOSEPHUS PROBLEM
Each node contains a value, a link to its successor (if any), and a link to its
predecessor (if any)
The header points to the first node in the list and to the last node in the list (or
contains null links if the list is empty)
A simple node structure of a doubly linked list is shown below:
A node structure in doubly linked list is declared as follows:struct
node
{
struct node *left;
int data;
struct node *right;
};