0% found this document useful (0 votes)
28 views

Unit 12

Uploaded by

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

Unit 12

Uploaded by

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

Structure Page No.

12.1 Introduction
Objectives
12.2 Basic Terminology
12.3 Static Implementation of Lists
12.4 Pointer Implementation of Lists
Storage of Sparse Arrays using Linked List
12.5 Doubly Linked Lists
12.6 Circular Linked List
12.7 Storage Allocation
12.8 Storage Pools
12.9 Garbage Collection
12.10 Fragmentation, Relocation and Compaction
12.1 1 Summary
12.12 Solutions/Answers

In Unit 11 of this Block we discussed a basic data structure, arrays. Arrays, although available
in almost all the programming languages, have certain limitations on structuring and accessing
data. In this Unit we turn our attention to another data structure called the List.

Lists, like arrays are used to store ordered data. A List is a linear sequence of data objects of the
same type. Real-life events such as people waiting to be served at a bank counter or at a railway
reservation counter, may be implemented using List swuctures. In computer science. Lists are
extensively used in data base management systems, process management, operating systems,
editors etc.

In Sec. 12.2, we introduce basic terminology related to Lists. In Sec. 12.3, we discuss static
implementation of Lists using arrays. In Sec. 12.4, we discuss dynamic implementation of lists
using pointers. We also discuss various operations that can be performed on a List like insertion
of an element, deletion of an element etc. We had already seen how to store sparse matrices
using arrays in Unit 11. Here, we will discuss storage of sparse arrays using linked Lists. In
Sec. 12.5, and Sec. 12.6, we will discuss some variants of linked Lists called doubly linked Lists
and circular linked Lists, respectively. In the last two sections, we will discuss some
applications of lists to garbage collection and storage allocation.

After studying this unit, you should be able to


store data structures in computer memory in two different ways viz. sequential allocation and
linked allocation;

differentiate between a linear list and an array;

implement linear lists in terms of built-in data types in C;

code following algorithms using a linked list represented as an array of records;

creating a linked list


inserting an element at a specified location in a linked list
deleting an element from a linked list.
LIST(0)
LIST(1)
Fl
LIST(2) YELLOW
LIST(3) GREEN
LIST
Lists

LIST(6)
LIST(7) used

Fig. 1: A list declared as an array.

The predecessor of LIST[O] (or head) is NIL; LIST[4] is the tail of the List and has no
successor. We may also tabulate the predecessors and successors of the other elements of the
List as in Table 1.
Table 1: Predecessors and successors.

Unused
locations

Since the elements are sequentially stored, we don't need to store the predecessor and successor
indices. Any element in the List can be accessed through its index.

Now let us see an Insert operation. If we want to insert an element at Kth position i.e. after
LIST[K- 11.

To do this we must shift elements LIST[K] through LIST [Last] to respectively LIST [K+1]
through LIST [Last+{]. At the same time we must also check that Last + 1 does not exceed the
value of SIZE.

LIST[Last] is nothing but the tail of the List.

Let us see the operations to be performed in an algorithmic form.


/*Check i f Last+l i s l e s s than o r equal t o Size*/
i f (Last + 1 > List-size - 1 )
e r r o r ; /*overflow*/
else{
/ * S h i f t i n g elements from K + 1 through Last + l*/
f o r ( i = Last; i > K; i--)
L i s t [ i ] = L i s t [i-11 ;
/*Insert element i n the Kth position*/
L i s t [K]=element
Last=Last+l;
In the delete operation we need to shift element in upwards direction and also decrement the
value of tail by 1.

Example 2: Let us now write a C program that creates a list that can hold 10 strings. We will
set the sets the first five elements to BLUE, RED, YELLOW, GREEN and ORANGE. Then we
Data Structures will insert CYAN in the third position.
/*Program-12.1.Examp of List implementation using a r r a y .
File name:unitl2-listarray.c*/
#include tstdio.h>
#include <string.h>
#define MAX-L 10
#define MALWD 20
int last=O;
in t ins-element (char array[MAX-L] [MAX-WD] , i nt pos, char *text) ;
int del-element(char array[MALL][MALWD], Int pos);

int main()
char colours[MAX_L][MAX-WD];
int i;
for (i = 0; i < M&L; i++)
strcpy(colours[i] , "-") ;
ins-element(colours. 0. "BLUE");

. . . .

ins~element(colours, 3, "GREEN");
ins-element(colours, 4, "ORANGE");
print-array(co1ours);
ins-element(colours. 2. "CYAN"):
del-element (colours , 3) ;
print-array(co1ours);
return 0;

Here is the function that inserts an element in a list.


int ins-element(char array[MAX-L][MAX-WD], int pos, char *text)
C
int j = MAX-L - 1;
if (last >= j)(
Error("Error! Overflow! ! " ) ;
1
else(

3
return 0;
1
We use the Error ( ) function that we used in the answer to exercise 1 of Unit 1I to print an
error message if the list is already full. Here is the function that deletes a particular element
from the list.
int del-element(char array[MALL][MAX-WD], int pos)
int i ;
for (i = pos; i < M A L L - 1; i++)
strcpy(array[i - I], array[i]) ;
strcpy(array[MAX-L - 11, "-");
last = last-1;
return 0:

26 You may recall that list [i] is a pointer to the ith row of the array. Also, note the use of
atP S t ~ c t u r e ~ item in the List. This will become more apparent below, after we have exam~nedsome of the
basic properties of Linked Lists and some of the fundamental operations we perfom on them.

Now, this explicit representation of the ordering allows certain operations to be performed much
more efficiently than would be possible for arrays. For example, suppose that we want to move
the GREEN to the beginning of the List. In an array, we would have to move every item to
make room for the new item at the beginning; in a linked List, we just change three links.

Let us now to write a C program that create a linked list w ~ t hthe colours BLUE, RED,
YELLOW and GREEN. We will d o this in stages.

Example 3: We start by defining a seBf referential structure called node. This is called a self
referential structure because the second component of the structure is a pointer to another
structure of the same type. Instead of referr~ngto this again and again as struct node,we use
the typedef statement to create a new type called Node. Iiere is a small program that creates a
linked list containing one node. Let us examine t h ~ program.
s

1 /*Program 12.2. Example node creation in


2 Linked lists. File name:unitlZ-myfirstll .c*/
3 #include Cstdio. h>
4 #include <string. h>
5 #include <stdlib.h>
6 #define MAX-WD 20
7 struct node{
8 char colour[MAX-WD];
9 struct node *next;);
10 typedef struct node Node;
1 1 Node *CreateNode(char acolour);
12 void Error(char *message);
13 int main()
14 (
15 Node *head = NULL;
16 head=CreateNode("REDU);
17 printf("%sH, head->colour);
18 return 0;
19 1
20 Node *CreateNode(char *Colour)
21
22 Node *ptr;
23 if ((ptr = malloc(sizeof (Node))))(
24 ptr->next= NULL;
25 strcpy(ptr->colour,Colour);
26 return (ptr) ;
27 1
28 else{
29 Error("Unab1e to create node!");
30 return (ptr);

32 1
33 void Error(char *message)
fprintf(stderr,"Error! %s\nn,message);

In lines 7 to 9 of this program we define a self referential structure called node. The first
component of this structure is a character array of slze MALW which we have #defined to be
20 earlier in line 6.
Line 20 calls the function CreateNodeO and assigns the value returned by it to the pointer
head. As we will see, CreateNodeO returns a pointer to a newly created node and head
will also point to this node. The function CreateNodeO creates a node with the colour
passed to it as argument. The function calls malloc () to allocate memory and assigns the Lists
pointer returned by malloc () to the local variable ptr which is a pointer to Node. If the
malloc () is unable to allocate memory it will return NULL pointer. In this case, the value of
the expression ptr=malloc (sizeof(Node)) will be 0 and so the else part part of the if
statement will print an error message. Otherwise, the line ptr->next=NULL initialises the
node to NULL and copies the name of the colour, which is a string, on to colour part of the
Node. L~ne26 returns the pointer to the main program. The printf ( ) statement in line 17
checks if the node has been created successfully. The situation after creation of the node is
given in Fig. 3. Throughout this example, we will say 'the node RED', 'the node BLUE' etc

I Head

Fig. 3: A linked list with one node.

instead of saying 'the node containing RED', 'the node containing BLUE' etc.

We will now see how to insert a node at the beginning of the list. We will now insert a new node
containing the colour BLUE at the beginning of the list. Here are the steps involved(We have
shown the steps in Fig. 4 on the next page.):
a) Create a new node using CreateNodeO function and make new point to the same
location as the pointer returned by CreateNode ( )

new = CreateNode("BLUE");

b) Make the pointer in the the new point to where head points, i.e. the node RED.

new->next = head;

c) Make the pointer head ~ o i nat -


t the new node. making it the first node.

head = new;
Let us now add the colour GREEN at the end of the list.
a) We need a pointer to the last node. We make pointer current point to Node and initially
make it point to the same node as head. See Fig. 5a on the following page.

current = head;

b) Then, we advance current till it points to the last node in the list through a while loop:

while (current->next != NULL)


current = current->next;
Initially, current points to the node containing BLUE. So, current->next is a
pointer to where the pointer in the node containing BLUE points; this is the node
containing RED. Since this isn't NULL,the statement in the which loop is executed. The
effect of the statement 'current=current->next ;' is to make current point to
I the where the pointer in the node corresponding to BLUE points; this is the node
containing RED. But, the pointer in the node corresponding to RED points to the NULL
polnter and so the condition in the while loop is not satisfied. Now, we have the pointer
current pointing to the last node, namely the one corresponding to RED.
/ Data Structures

BLUE I RED

(a) Create new node (b) Make the pointer in Blue to point to RED.

1 head

(c) Make the pointer head point blue.

Fig. 4: Inserting a new node at the beginning of a list.

BLUE I RED
I
(a) Create a new pointer to the first node.

BLUE I

(b) Advance the pointer Current to point to


RED

(c) Create a new node and set the value of name to GREEN and make the
pointer in RED point to GREEN

Fig. 5: Adding a new node at the end of a list.

c) As before, we create a new node, set the first component of the node as GREEN.
new = CreateNode("GREENW);
current->next = new;
new->next = NULL;
Then, we use the statement current->next=new to make the pointer in the node
corresponding RED point to the newly created node. Finally, we make the pointer in the
newly added node point to NULL since this is the last node.
Let us see how we can add a node in the middle of a linked list. Let us add a node
corresponding to YELLOW after RED. Here are the steps involved. See Fig. 6.
1) c u r r e n t point to the first node.
Make
2) Advance c u r r e n t to point to the node contain~ngRED. Use a new pointer called prev
Make prev and c u r r e n t point to the same node.
3) Advance c u r r e n t to point to the next node containing GREEN.
Lists

BLUE * RED - GREEN

(a) Make current point to the first node.

1 head 1 current 1prev


t t t
*-
BLUE
. RED GREEN

(b) Make Current and a new pointer preV point to the node after which we
want to insert the new node.

head prev current


L

BLUE + RED m- GREEN

(c) Advance current to point to the next node.

1 head 1 rev I current

(d) Make the pointer in RED point to the new node and the pointer in the new node
point to GREEN

Fig. 6: Adding a node in the middle.

4) Create a new node. We have to make this pointer in this new node point to the node
containing RED. The pointer current points to GREEN.So, the statement
new->next=current ; makes new->next also point at GREEN. Then, we have to
make the pointer in the node containing RED to point to the new node. The pointer prev
points to RED; so we can achieve this using the statement prev->next=new ; .
Here is the complete listing of the C program.
/;rProgram t o demonstrate t h e creation and i n s e r t i o n o f nodes
i n a linked l i s t . File name: u n i l 2 - m y f i r s t l l - 2 . c;:-/
#include <stdio.h>
#include <string. h>
#include tstdlib. h>
#define W W D 20
struct node{
char colour [MAX-WD] ;
struct node *next;);
typedef struct node Node;
Node nCreateNode(char *colour);
void Error(char *message) ;
void printlist(Node * ) ;
i n t main()
C
Node *head, *new, *current, 3cprev;
Data Structures 17 head = NULL;
18 head = CreateNode("REDH);
19 new = CreateNode("BLUEU);
20 new->next = head;
21 head = new;
22 /*Insert node GREEN a t the end. */
23 current = head;
24 while (current->next ! = NULL)
25 current = current->next;
26 new = CreateNode("GREEN");
27 current->next = new;
28 new->next = NULL;
29 printlist(head);
30 /*Insert YELLOW a f t e r RED */
31 current = head;
32 /*current points t o BLUE */
33 current = current->next;
34 /*Current points t o RED now */
35 new = CreateNode("YELL0W");
36 prev = current;
37 /*save the value o f current i n prev.
38 prev points t o RED now. */
39 current = current->next;
40 /*current points t o GREEN now. */
41 new->next = current;
42 /*Make t h e pointer i n the new node also
43 t o point a t GREEN */
44 prev->next = new;
45 /*The pointer i n RED points t o
46 the new node containing YELLOW.
47 Print the l i s t for checking. */
48 printlist(head);
49 return 0;
50 1
51 Node tCreateNode(char *Colour)
52
53 Node *ptr;
54 i f ((ptr = malloc(sizeof (Node))))(
55 ptr->next= NULL;
56 strcpy(ptr->colour,Colour);
57 return(ptr);
58 1
59 else{
60 Error("Unab1e to create node!"1 ;
61 return (ptr) ;
62 1
63 3
64 void Error(char *message)
65 {
66 fprintf(stderr,"Error! %s\n",message);
67 1
68 void printlist(Node *ptr)
69
70 while (ptr->next){
71 printf("%s\n",ptr->colour);
72 ptr=ptr->next;
73
74
75
76
He]-e is an exercise to test your understanding of the earlier material. Lists

L
E2) Wrlte a program that creates a linked List with entries 1, 2, 3,4 and 5.
I

The aim of the example above was to help you understand the process of creating nodes.
Obviously, the procedure will be tedious if we want to create a list with 100 nodes. In practice.
we will need a function that creates and insert a new node. We will see how to d o this in the
next example.

Example 4: In this example, let us write functions for inserting new nodes in a list. First let us
write a function that adds a node at the beginning of an existing linked list.
void add-node(Node -.*headref, char cname[MAX-WD])
{
Node *new = CreateNode(cname);
new->next = *headref;
*headref = new;
1
. You may have noticed **headref, a pointer to pointer! Why do we need to do this?
Remember that, in C, if we want a function to change an object, we have to pass a pointer to the
object that we want to change. Here, when we add a new node, head will point to this new
node instead of wherever it was pointing before. Since, we want to change the contents of the
pointer variable head we have to pass a pointer to head, not just head. So, we will pass the
value of head by the statement add-node (&head). So, the function must accept a pointer
to a pointer variable.

Let us now write a function that inserts a new node at the nth position, regardless of where it is,
in the beginning, in the end or in the middle. The function will take the pointer to the head
pointer, the colour of the new node and the position where we want to insert the new node as the
arguments. The function should do the following:

If position = 0 call add-node() to insert a node at the beginning;


else
Create a new pointer called current and advance it point to position:
If current does not point to the last element of the list, pass the pointer current to
add-nodeaid () ;
elseif
Pass the pointer current to add-node-end().

Here is the function that inserts a node in the middle:


void add-nodeaid(Node **headref. char namerMAX-WD1)

P
current = *headref;
prev = current;
current = current->next;
new = CreateNode(name);
prev->next = new;
new->next = current:

i Here is a function that inserts a node in the end.


1 void adfinode-end(Node **headref. char namerMAX-WD1)
Node *current, *new;
current = *headref;
new = CreateNode(name);
Data Structures new->next = NULL;
current->next = new;
1
Here is a function that checks the position where we want to insert the node and call appropriate
functions to insert them in the correct position.
void ins-node(Node **headref, char cname[MAX-WD], int num)
/aFunction that i n s e r t s the colour cname
a f t e r num nodes */
{
Node *current;
i n t count = 1;
current = *headref;
i f (num == 0)
add-node(headref, cname);
else
{
while (count < num)
if (current->next == NULL)

printf("\nThere are only %d nodes.\nn, count);


printf("Cannot insert node after position %d.".
num) ;

1; /*End o f i f */
current = current->next;
count += 1;
1; /*End o f while */
/*check i f num i s the l a s t node. */
i f (current->next == NULL)
add-node-end(&current, cname);
else
add-node~id(&current. cname):

Here are some exercises to test your understanding of the previous example.

E3) Write a function that returns the number of nodes in the list we created in the previous
exam~le.

E4) Write a function that will delete the node after the nth node.
I
Let us now discuss an application of linked list, namely addition of two polynomials. Linked
lists are convenient when we have to add two polynomials of high degree with many
coefficients zero. For example, consider the problem of adding two polynomials.
I
x25- 1 2 ~ ' ~ + 5 ~ ~ - 8 x ~ andx2'-
+ x + l 1 2 x 1 4 + 7 x ' 0 + 7 x 4 + 2 x 3 + x + 9 . Ifweusearrays,
we will need three arrays, one of size 27, another of size 25 and a third one of size 27 to hold
the answer. Further, there are many terms which are 0 in both the polynomials, yet we have to
take them into account. We will see how to use linked lists to add these polynomials.

Example 5: Let us first define the structures that will hold the terms. Note the use of typedef
in this.
#include tstdio .h>
#include <stdlib.h>
typedef s t r u c t poly {
Lic
int c o e f f ;
int deg;
struct poly +next;

Let us now write a function in C that adds a term of a given degree and given coefficient to an
existing polynomial. The function assumes that polynomial is constructed in such a way,
starting from the head node, the terms are arranged in descending order with the head pointing
to the highest degree term. Given a term, it checks if the polynomial has any terms. If it doesn't
have any terms, it adds a new term. Otherwise, it inserts the term at an appropriate place. If there
is already a term with given degree, it adds the coefficient of the new term to the existing term.
Here is the full listing of the function with copious comments. Please go through it carefully.

void adhterm(Po1y .k* p o l y l , in t c o e f f , in t degree)

Poly anew, *current, tprev;


current = f ~ p o l y l ;
new = m a l l o c ( s i z e o f ( P o l y ) ) ;
new->coeff = c o e f f ;
new->deg = degree;
new->next = NULL;
/*The polynomial has no terms */
i f (*polyl == NULL)
frpolyl = new;

/* I f t h e term being added has higher degree than t h e


highest degree term i n p o l y l , add t h e term i n the beginning :t/
i f (current->deg < degree) {
dw->next = current ;
*polyl = new;
} else {
/* Advance current till i t points t o the l a s t term(node) or
t o a term o f degree not greater than the degree o f t h e terms
we want t o i n s e r t . */
while (current->deg > degree && current->next != NULL)
current = current->next;
/ * I f we have reached t h e l a s t term o f poly and the degree
o f the l a s t term i s greater than that o f t h e term we want
t o i n s e r t , add the term a t t h e end. */
i f (current->next == NULL && current->deg > degree)
current->next = new;
else {
/ * I f we have found a term with t h e same degree as the term we
want t o i n s e r t , merely add t h e c o e f f i c i e n t o f the term we want
t o i n s e r t t o c o e f f i c i e n t o f the e x i s t i n g term o f the same degree; */
i f (current->deg == degree) {
current->coeff = current->coeff + c o e f f ;
} else (
/*otherwise add a new term. */
prev = current;
current = current->next;
prev->next = new;
new->next = current;

***
Here are some exercises for you to check your understanding of the representing polynomials
using linked lists.
Data Structures
typedef struct dlnode {
int data;
struct dlnode *left;
st r uct dlnode *right ;
) Dlnode;

Since there are nodes in both the directions, the traversal of the List can be in any direction. We
have a structure as given in Fig. 9. Note that the left link of leftmost node and right link of
riehtmost node are NULL.

I Fig. 9: A doubly linked list.

Insertion of a Node

To insert a node into a doubly linked List to the right of a specified node, we have to consider
several cases. These are as follows:
1. If the List is empty, i.e. the left and right link of specified node pointed to by say variable
HEAD are NULL. An insertion in this node is simply making left and right pointers point
to the new node and left and right pointers of new node to be set to NULL.
2. If there is a predecessor and a successor to the given node. In such a case we need to
readjust pointers of the specified node and its successor node. The procedure is shown
in Fig. 10.

Left
[ NIL] I DATA ~NIIJ

DATA

Fig. 10: Insertion in doubly linked list.

1 3. The insertion is to be done after the right most node in the List. In such a case only the
right link of the specified node i.e. the rightmost node is to be changed.
Here is a function that creates a new node and returns a pointer to it.
Dlnode *getnode()
Dlnode *p;
p = malloc(sizeof (Dlnode));
return (p);
I
Were.is a function that inserts a node before the node at POS.
void ins-dlnode-lt(D1node ** dlptr, int x, int pos)
Dlnode *current, *new, *prev;
int count = 1;
ata Structures if (*dlptr == NULL) {
printf("Unab1e to insert to the left.");
I
exit (1);
3;
i f (pos == 1) {
/*When the node has t o be inserted a t the s t a r t o f
l i s t . */
new = getnode();
current = *dlptr;
*dlptr = new;
new->data = x;
new->right = current;
new->left = NULL;
3 else {
/*Advance t h e pointer. */
f o r ( ; count < pos; count++)
current = current->right;
/*Create a new node. */

/*prev s t o r e s the node t o t h e l e f t o f the pas*/


prev = current->left;
current->left = new;
new->left = prev;
prev->right = new;
new->right = current;
3
3
Here is a function that inserts a node after the node at poS postion.
void ins-dlnode-rt(D1node ** dlptr, int x, int pos)
Dlnode *prev, *current, *new;
i n t count = 1;
current = *dlptr;
i f (ndlptr == NULL) {

if (pos == 1) {
new = getnode();
new->right = NULL;
new->left = NULL;
new->data = x;

new = getnode();
new->data = x;
f o r ( ; count < pos; count++)
current = current->right;
prev = current;
current = current->right;
new->left = prev;

Here is a small program that illustrates the use of these functions.


#include tstdio .h>
#include <stdlib.h> Lists
typedef struct dlnode {
i n t data;
struct dlnode *left;
st r u c t dlnode *right ;
1 Dlnode;
Dlnode *getnode() ;
void ins-dlnode,rt(Dlnode ** dlptr, int x, int pos);
void ins-dlnode-lt(D1node ** dlptr, Int x, i n t pos);
i n t print-dllist(D1node * dlptr);
i n t main ()
t
I Dlnode *head = NULL;
I ins-dlnode-rt(&head,
I print-dllist(head);
ins-dlnode-lt(&head,
1, 1);
2, 1);
print-dllist (head) ;
I ins-dlnode-rt (&head, 3, 2) ;
Y print-dllist(head);
ins-dlnode-lt(&head, -1, 1);
print-dllist(head);
, return 0;
1
You may find it instructive to make diagrams like the ones we did in example 4 for these
operations.

You may have noticed that the program uses a function to print the list. You may like to write
one on your own. We have left it as an exercise to you. Try the following exercises.

b
E7) Can you guess what will be the contents of the list at the end of the program above?

E8) Write a function that prints the contents of the doubly linked list.

Another way of overcoming the disadvantages of singly linked List is a circular List. We
discuss circular Lists in the next section.

- --

12.6 CIRCULAR LINKED LIST


Another alternative to overcome the drawback of singly linked List structure is to make the last
element point to the first element of the List. The resulting structure is called a circularly
linked List ( Fig. 11). A circularly linked List is a List in which the link field of the last element

DATA

Fig. 11: A Circular list.

of the List contains a pointer to the first element of the List. The last element of the List no
longer points to a NULL value.

The definition of circular list is similar to that of circular list. Insertion of nodes in the middle is
similar. However, insertion at the end or in the beginning is different. We leave it to you to
modify the functions that we wrote for singly linked list for a circular list.
Data Structures

E9) Modify the functions that we wrote for inserting nodes in a linked list for a circular list.

We conclude this section here. In the next section, we discuss storage allocation.

12.7 STORAGE ALLOCATION


Initially, the operating system determines the areas available for allocation to users. We will use
the term 'node' to designate a Unit of the storage space.

Nodes are allocated to users in response to their requests. The number of nodes and the size of
each node are decided keeping the following factors in mind.
1) Contiguity of space improves performance, especially for sequential access.
2) Having a large number of nodes leads to greater storage management effort.
3) Having fixed size nodes can lead to wastage of space.
The trade off can be summarised as:
I) Large nodes provide contiguous space and hence improve performance. They should be
variable in size to prevent excessive wastage of space.
2) Small nodes improve flexibility. Much space is not wasted but their management is
complex.
Having once decided the number and size of the nodes we now turn our attention to the actual
allocation of these nodes. We make the assumption that we have multiple nodes of varying sizes
and we want a storage space of size M. This can be done in one of the following ways:

1. Best Fit Method

All available nodes are checked. Assuming the size of a node is represented by N.

The node whose value of N gives the least value for D is chosen and allocated.

The advantages of this method are obviously the minimal wastage of space.

The disadvantages are

it involves searching all available nodes.

it tends to increase the number of very small free blocks, when D not equal to 0.2.

2. First Fit Method

The available nodes are checked till we find one whose size N is greater than or equal to M, the
requested size.

The advantage of this is obviously a smaller search among the available List of nodes. The
disadvantage, like in the Best fit method could be that very small free blocks could be created.
The way out of this is to fix a reasonable size C such that on getting the node of size NM,

allocate the entire node of size N

Else
Allocate space of size M Lists

reserve node of size (n-M) for further use.

The collection of all nodes available is the Storage Pool. We will now deal with the
1 management of this pool. This can be done in one of the following ways:

This method uses an array containing one bit per node. It is generally used when all nodes
are of the same size, usually 1"block. A bit value of '0' indicates that the corresponding
node is free, and a value of '1' indicates that it has been allocated. A separate file
mechanism is needed to indicated the nodes allocated to a specific file. The advantages of
this system are that the table can be kept in core memory so that allocation and deallocation
(i.e. setting the bits to '1' or '0') costs are minimal.
2) Table of Contents

unit. This file will have (typically) the following data for each node - its size, whether

j allocated or not, if allocated - the name of the file, owner's identification, date of creation
etc.
Like the bit table, this table of contents has to be searched to find free space for allocation.
I This problem may be overcome by keeping the records of free nodes in the 'Free Space
Table of Contents'. Allocation then means gettlng a suitable node from the 'Free Space

I
l
3)
Table of Contents' and moving it to the 'Table of Contents' after suitable updating. Freeing
a node implies the reverse process.
Linked allocation
Nodes can be linked together to overcome the limitations of the above two methods. In this
method, each node will have a link to the next node in the List. Initially all nodes will be
part of a free nodes List. On allocation to a file, a node will be detached from the free space
List and added to the allocated List for that file. When a node is deallocated, it is detached
from the allocated List of the file and attached to the free nodes List.
Linked Lists have been discussed in an earlier section. Thus we know Linked Lists can be
singly or doubly linked depending upon the needs. This method provides an implicit gain
in storage - in cases where Tables or diles overlap, sharing common parts. The set of
common nodes can be part of the allocation Lists of all the sharing tables.
The advantages of linked allocation are directly related to the case of operations on Linked
Lists. Simple insertion and deletion from a linked List implies simplicity in
insertingfdeleting from a file. Ease of combination of Lists implies ease of joining files.

Deallocation of nodes can take place in two levels:

1) The application which claimed the node releases it back to the operating system.
i
2) The operating system calls storage management routines to return free nodes to the free
space.
1
For.example Deallocation as in (1) occurs in a C, program with the statement free(x) where
x is space earlier allocated by a malloc call. (2) is usually implemented by the method of
1 Garbage Collection. This requires the presence of a 'Marking' bit on each node. It runs in two
phases. In the first phase, all non-garbage nodes are marked. In the second phase all !
non-marked nodes are collected and returned to the free mace. Where variable size nodes are 41 4
Data Structures d it is desirable to keep the free space as one contiguous block. In this case, the second phase
is called Memory compaction.

Garbage Collection is usually called when some program runs out of space. It is a slow process
and its use should be obviated by efficient programming methods.

12.10 FRAGMENTATION, RELOCATION AND


COMPACTION
Fragmentation literally means splitting. We have seen from our discussions in Sec. 12.7 that the
'Best fit' and 'First fit' algorithms result in creation of small blocks of space. These constitute
wastage of space as they can be used to satisfy only requests for small blocks. This can be
illustrated by the following example:

Consider the following space divided into three nodes of size 100 each. Q
A (Size: 100) 1 I
B (Size: 100) 1
c (Size: 100) I I
The following have to be allocated using first fit:
1) Size 50. This can be allocated from A. So, we get

2) Size 80. This can be allocated from B.

I I

3) Size 20. This can be allocated from A.

A +- Occupied (Size: 50)


1 +- Occupied (Size: 20)
b +- Free (Size: 30)
i B +- Free (Size: 80)
+- Free (Size: 20)
I
C +- Free (Size: 100) I
i 4) Size 50. This can be allocated from C.

t I 1 t Occupied (Size: 20)


I 1 +- Free (Size: 30)

Now there is no contiguous block of size 75 though the actual space available is
30+20+50= 100

In this state of fragmentation, only requests of size _< 50 can be satisfied.


n t h node F i l e name: uni tl2-ans-ex-4. c . */
void delxode(Node **headref, i n t num)
i n t count;
Node *currentlatemp;
current=*headref;
/*current now p o i n t s t o t h e head o f t h e l i s t . */
i f (num==O){
/*We want t o d e l e t e the f i r s t node. */
*headref=current->next ;
/*Make head point a t t h e second node. */
free(current);
/*Free the memory used b y t h e first node. */

for(count = 0;count < num-1 ;count++)


current=current->next;
temp=current->next;
current->next=current->next->next;
free(temp) ;

You might also like