Cs3301 Data Structures U.I
Cs3301 Data Structures U.I
UNIT I LISTS
INTRODUCTION
DATA STRUCTURE
Data Structure is a way of organizing and retrieving data in such a way that we
can perform operations on these data in an effective way.
Data structures are generally categorized into two classes: primitive and non-
primitive data structures.
Meenakshi.R Page 1
Primitive data structures are the fundamental data types which are supported
by a programming language. Some basic data types are integer, real, character,
and boolean.
Non-primitive data structures are those data structures which are created
using primitive data structures. Examples of such data structures include linked
lists, stacks, trees, and graphs. Non-primitive data structures can further be
classified into two categories: 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.
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.
An abstract data type (ADT) is a set of operations. How the set of operations is
implemented is not mentioned
Stacks
Queues
Linked List
Modification: any desired element can be deleted from the data structure.
1. It is reusable, robust
2. It can be re-used at several places and it reduces coding efforts
3. Encapsulation ensures that data cannot be corrupted
2. LIST ADT
If the element at position i is Ai then its successor is Ai+1 and its predecessor is
Ai-1.
Meenakshi.R Page 3
4. Next (i) - Returns the position of its successor element.
1. Array Implementation
Creation
void create( )
scanf("%d", &b[i]);
}
Meenakshi.R Page 4
Insertion
void insert( )
scanf("%d", &pos);
if(pos >= n)
else
++n;
b[i] = b[i-1];
scanf("%d", &e);
b[pos] = e;
display();
Meenakshi.R Page 5
Deletion
Deletion refers to the operation of removing another element from the list
at the specified position.
When we delete an element from a position, the elements after that
position are move backward one position.
void deletion( )
scanf("%d", &pos);
if(pos >= n)
else
b[i-1] = b[i];
n--;
Meenakshi.R Page 6
display();
Searching
void search( )
int flag = 0;
scanf("%d", &e);
if(b[i] == e)
flag = 1;
Meenakshi.R Page 7
break;
if(flag == 0)
Traverse or Display
void display( )
Drawbacks in arrays:
• Has a fixed size.
• Data must be shifted during insertions and deletions.
Meenakshi.R Page 8
While declaring arrays, we have to specify the size of the array, which
will restrict the number of elements that the array can store. For example,
if we declare an array as int marks [10], then the array can store a
maximum of 10 data elements but not more than that.
But what if we are not sure of the number of elements in advance?
Moreover, to make efficient use of memory, the elements must be stored
randomly at any location rather than in consecutive locations.
So, there must be a data structure that removes the restrictions on the
maximum number of elements and the storage condition to write efficient
programs.
A singly linked list is a linked list in which each node contains only one link
field pointing to the next node in the list.
Meenakshi.R Page 9
Header node points to the first node in the list
NODE DECLARATION
struct Node
int Element;
};
if(L->next == NULL )
return 1;
else return 0;
INSERTION:
Meenakshi.R Page 10
4. Set the next field of the new node to the successor of current node
5. Set the next field of the current node to newnode.
Position Newnode;
if (Newnode! = NULL)
P ->Next = Newnode;
SEARCHING:
Start from the first node and compare the data part with element to be
searched
If it is present then the corresponding position is returned.
Meenakshi.R Page 11
Position Find (int X, List L)
Position P;
P = L -> Next;
P = P ->Next;
return P;
Position P;
P = L;
P = P -> Next;
return P;
}
Meenakshi.R Page 12
DELETION:
Position P, Temp;
P = Findprevious (X,L);
Temp = P ->Next;
Free (Temp);
TRAVERSE OR DISPLAY:
void Traverse(List L)
Meenakshi.R Page 13
Position P;
P= L->next;
printf("\n");
while(P!=NULL)
P=P-> next;
printf("NULL");
Circular linked list is similar to normal linked list except that the last node
contains a pointer to the first node of the list.
Types
In a singly circular linked list the pointer of the last node points to the first node.
In a doubly-circular-linked list both the last and first nodes point to each other
Meenakshi.R Page 14
Singly circular linked list
In a singly circular linked list the pointer of the last node points to the first node.
NODE DECLARATION
struct Node
int Element;
};
List L;
L=malloc(sizeof(struct Node));
L->Next = L;
INSERTION
Position Newnode;
if (Newnode! = NULL)
P ->Next = Newnode;
Meenakshi.R Page 16
SEARCHING:
1. Start from the first node and compare the data part with element to be
searched
2. If it is present then the corresponding position is returned.
Position P;
P = L -> Next;
P = P ->Next;
if(P!=L)
return P;
else
return NULL;
DELETION:
Meenakshi.R Page 17
Position FindPrevious (int X, List L)
{
/* Returns the position of the predecessor */
Position P;
P = L;
while (P Next ! = L && P Next Element ! = X)
P = P Next;
if(P!=L)
return P;
else
return NULL;
}
TRAVERSE OR DISPLAY:
void Traverse(List L)
{
Position P;
P= L->next;
printf("\n");
while(P!=L)
{
printf("%d -> ", P->Element );
P=P-> Next;
}
printf("END");
}
Meenakshi.R Page 18
DOUBLY CIRCULAR LINKED LIST
A Doubly linked list is a linked list in which each node has three fields
namely data field, forward link (FLINK) and Backward Link (BLINK).
FLINK points to the successor and BLINK points to the predecessor.
In a doubly-circular-linked list both the last and first nodes point to each
other.
Node declaration
struct Node
{
int Element;
struct Node *FLINK;
struct Node *BLINK
};
typedef struct Node* Position;
typedef struct Node* List;
List L;
L=malloc(sizeof(struct Node));
L->FLINK = L;
L->BLINK = L;
Meenakshi.R Page 19
7. DOUBLY LINKED LIST
A Doubly linked list is a linked list in which each node has three fields
namely data field, forward link (FLINK) and Backward Link (BLINK).
FLINK points to the successor and BLINK points to the predecessor.
Node declaration
struct Node
int Element;
};
INSERTION:
DELETION:
Meenakshi.R Page 21
2. Set the FLINK of predecessor node as the FLINK of current node
3. Set the BLINK of successor node as the BLINK of the current node
4. Free the memory used by current node
SEARCHING:
Start from the first node and compare the data part with element to be
searched
If it is present then the corresponding position is returned.
Meenakshi.R Page 22
}
TRAVERSE OR DISPLAY:
void Traverse(List L)
Position P;
P= L->FLINK;
printf("\n");
while(P!=NULL)
P=P-> FLINK;
printf("NULL");
Advantages
Disadvantages
More memory space is required than singly linked list, since it has two pointers.
8. APPLICATION OF LISTS
Meenakshi.R Page 23
3. Multilists
9. POLYNOMIAL ADT
Addition
Multiplication
Differentiation
Polynomial ADT can be implemented using linked list. Linked list consists of
three parts.
1. Coefficient part
2. Power part
Meenakshi.R Page 24
EXAMPLE OF A POLYNOMIAL:
Meenakshi.R Page 25
node->next=NULL;
printf("\ncontinue(y/n):");
scanf("%c",&ch);
} while(ch=='y' || ch=='Y');
}
DISPLAYING THE POLYNOMIAL
void show(struct link *p)
{
while(p!=NULL)
{
printf("%dx^%d",p->coeff,p->pow);
p=p->next;
if(p->next!=NULL) printf("+");
}
}
ADDITION OF TWO POLYNOMIAL
void polyadd(struct link *poly1, struct link *poly2, struct link *poly)
{
while(poly1->next && poly2->next)
Meenakshi.R Page 26
{
if(poly1->pow > poly2->pow)
{
poly->pow = poly1->pow;
poly->coeff = poly1->coeff;
poly1=poly1->next;
}
else if(poly1->pow < poly2->pow)
{
poly->pow = poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
else
{
poly->pow=poly1->pow;
poly->coeff = poly1->coeff + poly2->coeff;
poly1=poly1->next;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
while(poly1->next || poly2->next)
{
if(poly1->next)
{
poly->pow=poly1->pow;
Meenakshi.R Page 27
poly->coeff=poly1->coeff;
poly1=poly1->next;
}
if(poly2->next)
{
poly->pow=poly2->pow;
poly->coeff=poly2->coeff;
poly2=poly2->next;
}
poly->next=(struct link *)malloc(sizeof(struct link));
poly=poly->next;
poly->next=NULL;
}
}
POLYNOMIAL MULTIPLICATION
void polymul(struct link *n1, struct link *n2, struct link *n)
{
struct link * n2beg=n2;
Meenakshi.R Page 28
while (n1)
{
struct link * temp=(struct link *)malloc(sizeof(struct link));
temp->next=NULL;
n2=n2beg;
while (n2)
{
temp->coeff = n1->coeff * n2->coeff;
temp->pow = n1->pow + n2->pow;
n2 = n2->next;
temp->next=(struct link *)malloc(sizeof(struct link));
temp=temp->next;
temp->next=NULL;
}
polyadd(temp,n,n);
n1 = n1->next;
}}
A second example where linked lists are used is called radix sort.
Radix sort is sometimes known as card sort, because it was used to sort
old-style punch cards.
If we have n integers in the range 1 to m (or 0 to m - 1) 9, we can use this
information to obtain a fast sort known as bucket sort.
We keep an array called count, of size m, which is initialized to zero.
Thus, count has m cells (or buckets), which are initially empty.
When a i is read, increment (by one) count [a i ].
Meenakshi.R Page 29
After all the input is read, scan the count array, printing out a
representation of the sorted list.
This algorithm takes O(m + n);
If m = (n), then bucket sort is O(n).
Radix sort is a generalization of this.
The easiest way to see what happens is by example. Suppose we have 10
numbers, in the range 0 to 999, that we would like to sort. Use several
passes of bucket sort.
Perform bucket sorts by least significant "digit" first, then the algorithm
works. Of course, more than one number could fall into the same bucket,
and, unlike the original bucket sort, these numbers could be different, so
we keep them in a list.
The following example shows the action of radix sort on 10 numbers.
The buckets are as shown in Figure 3.24, so the list, sorted by least significant
digit, is 0, 1, 512, 343, 64, 125, 216, 27, 8, 729.
------------------------------------------- -------------------------------------------------
0 1 2 3 4 5 6 7 8 9
These are now sorted by the next least significant digit (the tens digit here) (see
Fig. 3.25).
Meenakshi.R Page 30
Pass 2 gives output 0, 1, 8, 512, 216, 125, 27, 729, 343, 64.
This list is now sorted with respect to the two least significant digits.
The final pass, shown in Figure 3.26, bucket-sorts by most significant digit.
The final list is 0, 1, 8, 27, 64, 125, 216, 343, 512, 729.
The running time is O(p(n + b)) where p is the number of passes, n is the
number of elements to sort, and b is the number of buckets.
In our case, b = n.
11. MULTILISTS
Our last example shows a more complicated use of linked lists. A university
with 40,000 students and 2,500 courses needs to be able to generate two types
of reports. The first report lists the class registration for each class, and the
second report lists, by student, the classes that each student is registered for.
Meenakshi.R Page 31
The obvious implementation might be to use a two-dimensional array. Such an
array would have 100 million entries. The average student registers for about
three courses, so only 120,000 of these entries, or roughly 0.1 percent, would
actually have meaningful data.
What is needed is a list for each class, which contains the students in the class.
We also need a list for each student, which contains the classes the student is
registered for. Figure 3.27 shows our implementation.
As the figure shows, we have combined two lists into one. All lists use a header
and are circular. To list all of the students in class C3, we start at C3 and
traverse its list (by going right). The first cell belongs to student S1. Although
there is no explicit information to this effect, this can be determined by
following the student's linked list until the header is reached. Once this is done,
we return to C3's list (we stored the position we were at in the course list before
we traversed the student's list) and find another cell, which can be determined to
belong to S3. We can continue and find that S4 and S5 are also in this class. In a
Meenakshi.R Page 32
similar manner, we can determine, for any student, all of the classes in which
the student is registered.
Using a circular list saves space but does so at the expense of time. In the
worst case, if the first student was registered for every course, then every entry
would need to be examined in order to determine all the course names for that
student. Because in this application there are relatively few courses per student
and few students per course, this is not likely to happen. If it were suspected
that this could cause a problem, then each of the (nonheader) cells could have
pointers directly back to the student and class header. This would double the
space requirement, but simplify and speed up the implementation.
Meenakshi.R Page 33