data structures unit-i - madhuravanimadhuravani.in/wp-content/uploads/2019/08/linkedlist.pdf ·...
TRANSCRIPT
B. Madhuravani
DATA STRUCTURES UNIT-I
UNIT-I
Basic concepts- Algorithm Specification-Introduction, Recursive algorithms, Data Abstraction
Performance analysis- time complexity and space complexity, Asymptotic Notation-Big O,
Omega and Theta notations. Data Structures – Introduction to Data Structures, abstract data
types. Linear list – singly linked list implementation, insertion, deletion and searching
operations on linear list, Circularly linked lists- Operations for Circularly linked lists, Doubly
linked list implementation, insertion, deletion and searching operations. Applications of linked
lists.
1. BASIC CONCEPTS
1.1 ALGORITHM SPECIFICATION
1.1.1 INTRODUCTION
The concept of an algorithm is fundamental to computer science. Algorithms exist for many
common problems, and designing efficient algorithms plays a crucial role in developing large-
scale computer systems. Therefore, before we proceed further we need to discuss this concept
more fully. We begin with a definition.
Definition: An algorithm is a finite set of instructions that, if followed, accomplishes a
particular task. In addition, all algorithms must satisfy the following criteria:
(1) Input: There are zero or more quantities that are externally supplied.
(2) Output: At least one quantity is produced.
(3) Definiteness: Each instruction is clear and unambiguous.
(4) Finiteness: If we trace out the instructions of an algorithm, then for all cases, the algorithm
terminates after a finite number of steps.
(5) Effectiveness: Every instruction must be basic enough to be carried out, in principle, by a
person using only pencil and paper. It is not enough that each operation be definite as in (3); it
also must be feasible.
2. RECURSIVE ALGORITHMS
A function is recursive if a statement in the body of the function calls itself. Recursion is the
process of defining something in terms of itself. For a computer language to be recursive, a
function must be able to call itself.
Advantages:
• Simplicity of code
• Easy to understand
Disadvantages:
• Memory
• Speed
All recursive algorithms must obey three important laws: 1. A recursive algorithm must have a base case.
B. Madhuravani
DATA STRUCTURES UNIT-I
2. A recursive algorithm must change its state and move toward the base case.
3. A recursive algorithm must call itself, recursively
Types of Recursions: 1. Direct Recursion
2. Indirect Recursion
3. Tail Recursion
4. Linear Recursion
5. Tree Recursion
1. Direct Recursion A C function is directly recursive if it contains an explicit call to itself
Example:
int foo (int x)
if ( x <= 0 ) return x;
return foo ( x – 1);
2. Indirect Recursion A C function foo1 is indirectly recursive if it contains a call to another function that
ultimately calls foo1.
Example:
int foo1(int x)
if (x <= 0) return x;
return foo2 (x);
int foo2 (int y)
return foo1(y – 1);
3. Tail Recursion Tail recursion is a form of linear recursion. In tail recursion, the recursive call is the last thing
the function does. Often, the value of the recursive call is returned. As such, tail recursive
functions can often be easily implemented in an iterative manner; by taking out the recursive
call and replacing it with a loop, the same effect can generally be achieved. In fact, a good
compiler can recognize tail recursion and convert it to iteration in order to optimize the
performance of the code.
A good example of a tail recursive function is a function to compute the GCD, or Greatest
Common Denominator, of two numbers:
int gcd(int m, int n)
int r;
if (m < n) return gcd(n,m);
r = m%n;
if (r == 0) return(n);
B. Madhuravani
DATA STRUCTURES UNIT-I
else return(gcd(n,r));
Example: Convert the following tail-recursive function into an iterative function:
int pow(int a, int b)
if (b==1) return a;
else return a * pow(a, b-1);
int pow(int a, int b)
int i, total=1;
for(i=0; i<b; i++) total *= a;
return total;
4.Linear Recursion It is the most common type of Recursion in which function calls itself repeatedly until base
condition [termination case] is reached. Once the base case is reached the results are return to
the caller function. If a recursive function is called only once then it is called a linear recursion.
Example:
int factorial (int n)
if (n == 0) return 1;
return n * factorial ( n – 1);
5.Tree Recursion A recursive function is said to be tree recursive (or non-linearly recursive when the pending
operation does invoke another recursive call to the function. Some recursive functions don't just
have one call to themselves; they have two (or more). Functions with two recursive calls are
referred to as binary recursive functions
Example:
int fib(int n)
if (n == 0) return 0;
if (n == 1) return 1;
return ( fib ( n – 1 ) + fib ( n – 2 ) );
Differences between recursion and iteration:
• Both involve repetition.
• Both involve a termination test.
• Both can occur infinitely.
Difference between Recursion and Iteration:
1. A function is said to be recursive if it calls itself again and again within its body whereas
iterative functions are loop based imperative functions.
2. Recursion uses stack whereas iteration does not use stack.
3. Recursion uses more memory than iteration as its concept is based on stacks.
4. Recursion is comparatively slower than iteration due to overhead condition of maintaining
stacks.
B. Madhuravani
DATA STRUCTURES UNIT-I
5. Recursion makes code smaller and iteration makes code longer.
6. Iteration terminates when the loop-continuation condition fails whereas recursion terminates
when a base case is recognized.
7. While using recursion multiple activation records are created on stack for each call where as
in iteration everything is done in one activation record.
8. Infinite recursion can crash the system whereas infinite looping uses CPU cycles repeatedly.
9. Recursion uses selection structure whereas iteration uses repetition structure.
Factorial of a given number:
The operation of recursive factorial function is as follows:
Start out with some natural number N (in our example, 5). The recursive definition is:
n = 0, 0 ! = 1 Base Case
n > 0, n ! = n * (n - 1) ! Recursive Case
Recursion Factorials:
5! =5 * 4! = 5 *___ = ____ factr(5) = 5 * factr(4) = __
4! = 4 *3! = 4 *___ = ___ factr(4) = 4 * factr(3) = __
3! = 3 * 2! = 3 * ___ = ___ factr(3) = 3 * factr(2) = __
2! = 2 * 1! = 2 * ___ = ___ factr(2) = 2 * factr(1) = __
1! = 1 * 0! = 1 * __ = __ factr(1) = 1 * factr(0) = __
0! = 1 factr(0) = __
5! = 5*4! = 5*4*3! = 5*4*3*2! = 5*4*3*2*1! = 5*4*3*2*1*0! = 5*4*3*2*1*1
=120
#include<stdio.h>
#include<conio.h>
int fact(int n)
int f;
if((n==0)||(n==1)) // check the condition for the n value
return(n);
else
f=n*fact(n-1); //calculate the factorial of n
return(f);
void main()
int n;
clrscr();
printf("enter the number :");
scanf("%d",&n);
printf("factorial of number %d", fact(n));
getch();
The Towers of Hanoi:
In the game of Towers of Hanoi, there are three towers labeled 1, 2, and 3. The game starts with
n disks on tower A. For simplicity, let n is 3. The disks are numbered from 1 to 3, and without
loss of generality we may assume that the diameter of each disk is the same as its number. That
is, disk 1 has diameter 1 (in some unit of measure), disk 2 has diameter 2, and disk 3 has
B. Madhuravani
DATA STRUCTURES UNIT-I
diameter 3. All three disks start on tower A in the order 1, 2, 3. The objective of the game is to
move all the disks in tower 1 to entire tower 3 using tower 2. That is, at no time can a larger
disk be placed on a smaller disk. Figure 3.11.1, illustrates the initial setup of towers of Hanoi.
The figure, illustrates the final setup of towers of Hanoi.
The rules to be followed in moving the disks from tower 1 tower 3 using tower 2 are as follows:
• Only one disk can be moved at a time.
• Only the top disc on any tower can be moved to any other tower.
• A larger disk cannot be placed on a smaller disk.
The towers of Hanoi problem can be easily implemented using recursion. To move the largest
disk to the bottom of tower 3, we move the remaining n – 1 disks to tower 2 and then move the
largest disk to tower 3. Now we have the remaining n – 1 disks to be moved to tower 3. This
can be achieved by using the remaining two towers. We can also use tower 3 to place any disk
on it, since the disk placed on tower 3 is the largest disk and continue the same operation to
place the entire disks in tower 3 in order. The program that uses recursion to produce a list of
moves that shows how to accomplish the task of transferring the n disks from tower 1 to tower
3 is as follows:
#include<stdio.h>
#include<conio.h>
void Hanoirecursion(int num,char ndl1,char ndl2,char ndl3)
if(num==1)
printf("Move top disk from needle %c to needle %c",ndl1,ndl2);
return;
Hanoirecursion(num-1,ndl1,ndl3,ndl2);
printf("Move top dis from needle %c to needlle %c",ndl1,ndl2);
B. Madhuravani
DATA STRUCTURES UNIT-I
Hanoirecursion(num-1,ndl3,ndl2,ndl1);
void main()
int no;
clrscr();
printf("Enter the no. of disk to be transferred:");
scanf("%d",&no);
if(no<1)
printf("\n There's nothing to move");
else
printf("\n recursive");
Hanoirecursion(no,'A','B','C');
getch();
Output:
Enter the no. of disk to be transferred :3
Move top disk from needle a to needle b
Move top disk from needle a to needle c
Move top disk from needle b to needle c
Move top disk from needle a to needle b
Move top disk from needle c to needle a
Move top disk from needle c to needle b
Move top disk from needle a to needle b
Fibonacci Sequence Problem:
A Fibonacci sequence starts with the integers 0 and 1. Successive elements in this sequence
are obtained by summing the preceding two elements in the sequence. For example, third
number in the sequence is 0 + 1 = 1, fourth number is 1 + 1= 2, fifth number is 1 + 2 = 3 and
so on. The sequence of Fibonacci integers is given below: 0 1 1 2 3 5 8 13 21 . . . . . . . . .
A recursive definition for the Fibonacci sequence of integers may be defined as follows:
Fib (n) = n if n = 0 or n = 1
Fib (n) = fib (n-1) + fib (n-2) for n >=2
We will now use the definition to compute fib(5):
B. Madhuravani
DATA STRUCTURES UNIT-I
#include <stdio.h>
int fibonacci(int term);
int main()
int terms, counter;
printf("Enter number of terms in Fibonacci series: ");
scanf("%d", &terms);
printf("Fibonacci series till %d terms\n", terms);
for(counter = 0; counter < terms; counter++)
printf("%d ", fibonacci(counter));
return 0;
int fibonacci(int term)
if(term < 2)
return term;
return fibonacci(term - 1) + fibonacci(term - 2);
B. Madhuravani
DATA STRUCTURES UNIT-I
3. DATA ABSTRACTION
Data abstraction separates the specification of a data type from its implementation.
An abstract data type is a specification of a collection of objects and a set of operations that
act on those objects.
An abstract data type in a theoretical construct that consists of data as well as the operations to
be performed on the data while hiding implementation. For example, a stack is a typical abstract
data type. Items stored in a stack can only be added and removed in certain order – the last item
added is the first item removed. We call these operations, pushing and popping. In this
definition, we haven’t specified have items are stored on the stack, or how the items are pushed
and popped. We have only specified the valid operations that can be performed.
4. PERFORMANCE ANALYSIS
The performance of a program is the amount of computer memory and time needed to run a
program. When several algorithms can be designed for the solution of a problem, there arises
the need to determine which among them is the best. The efficiency of a program or an
algorithm is measured by computing –
Time Complexity
Space Complexity.
4.1 Time Complexity
The time complexity of an algorithm is a function of the running time of the algorithm. The
time complexity is therefore given in terms of frequency count. Frequency count is basically a
count denoting number of times of execution of statement.
Example1:
1
2
3
4
5
6
7
Algorithm Message(n)
for i=1 to n do
write(“Hello”);
0
0
n+1
0
n
0
0
total frequency count 2n+1
While computing the time complexity we will neglect all the constants, hence ignoring 2 and
1 we will get n. Hence the time complexity becomes O(n).
B. Madhuravani
DATA STRUCTURES UNIT-I
4.2 Space Complexity
• The space complexity can be defined as amount of memory required by an algorithm to
run.
• To compute the space complexity we use two factors: constant and instance
characteristics. The space requirement S(p) can be given as
S(p) = C + Sp
where C is a constant i.e., fixed part and it denotes the space of inputs and outputs. This space
is an amount of space taken by instruction, variables and identifiers.
Sp is a space dependent upon instance characteristics. This is a variable part whose space
requirement depend on particular problem instance.
Example:1 Algorithm add(a,b,c)
return a+b+c;
If we assume a, b, c occupy one word size then total size comes to be 3
S(p) = C (since C=3)
Example:2 Algorithm add(x,n)
sum=0.0;
for i= 1 to n do
sum:=sum+x[i];
return sum;
The n space required for x[], one space for n, one for i, and one for sum
S(p) ≥ (n+3)
5. ASYMPTOTIC NOTATIONS
• To choose the best algorithm, we need to check efficiency of each algorithm. The
efficiency can be measured by computing time complexity of each algorithm.
Asymptotic notation is a shorthand way to represent the time complexity.
• Using asymptotic notations we can give time complexity as “fastest possible”, “slowest
possible” or “average time”.
• Various notations such as Ω, θ, O used are called asymptotic notations.
5.1 Big Oh Notation
Big Oh notation denoted by ‘O’ is a method of representing the upper bound of algorithm’s
running time. Using big oh notation we can give longest amount of time taken by the algorithm
to complete.
Definition:
Let, f(n) and g(n) are two non-negative functions. And if there exists an integer n0 and constant
C such that C > 0 and for all integers n > n0, f(n) ≤ c*g(n), then f(n) = Og(n).
B. Madhuravani
DATA STRUCTURES UNIT-I
Various meanings associated with big-oh are
O(1) constant computing time
O(n) linear
O(n2) quadratic
O(n3) cubic
O(2n) exponential
O(logn) logarithmic
The relationship among these computing time is
O(1)< O(logn)< O(n)< O(nlogn)< O(n2)< O(2n)
Example:
Consider the function f(n) = 2n+2 and g(n)=n2, find constant C so that f(n)≤g(n), in other words
2n+2≤ n2 then find that for C = 1 or 2 f(n) is greater than g(n). That means when n=1 f(n)=4
and g(n)=1 for n=2, f(n)=6 and g(n)=4. When n > 2 we obtain f(n) < g(n). Then we obtain O(n2)
for
n > 2.
5.2 Omega Notation Omega notation denoted ‘Ω’ is a method of representing the lower bound of algorithm’s
running time. Using omega notation we can denote shortest amount of time taken by algorithm
to complete.
Definition:
Let, f(n) and g(n) are two non-negative functions. And if there exists an integer n0 and constant
C such that C > 0 and for all integers n > n0, f(n) >c*g(n), then f(n) = Ω g(n).
Example:
Consider f(n) = 2n+5 and g(n) = 2(n) then 2n+5≥2n for n>1. Hence 2n+5=Ω(n).
B. Madhuravani
DATA STRUCTURES UNIT-I
5.3 Theta Notation
Theta notation denoted as ‘θ’ is a method of representing running time between upper bound
and lower bound.
Definition:
Let, f(n) and g(n) are two non-negative functions. There exists positive constants C1 and C2
such that C1 g(n) ≤ f(n) ≤ C2 g(n) and f(n) = θ g(n)
Example:
If f(n)=2n+8>5n where n≥2; 2n+8≥6n where n≥2 and 2n+8<7n where n≥2. Hence 2n+8 = θ(n)
such that constants C1 = 5, C2 = 7 and n0 = 2.
Best Case, Worst Case and Average Case Analysis
• If an algorithm takes minimum amount of time to run to completion for a specific set of
input then it is called best case complexity.
• If an algorithm takes maximum amount of time to run to completion for a specific set
of input then it is called worst case time complexity.
• The time complexity that we get for certain set of inputs is as a average same. Then for
corresponding input such a time complexity is called average case time complexity.
B. Madhuravani
DATA STRUCTURES UNIT-I
6. DATA STRUCTURES
6.1 INTRODUCTION TO DATA STRUCTURES A data structure is a scheme for organizing data in the memory of a computer. Some of the
more commonly used data structures include lists, arrays, stacks, queues, heaps, trees, and
graphs.
Data structures and algorithms are interrelated. Choosing a data structure affects the kind of
algorithm you might use, and choosing an algorithm affects the data structures we use.
The way in which the data is organized affects the performance of a program for different tasks.
Computer programmers decide which data structures to use based on the nature of the data and
the processes that need to be performed on that data.
The data structure can be defined as the collection of elements and all the possible
operations which are required for those set of elements. In other words data structure will tell
us specific set of elements and corresponding set of operations.
A data structure can be defined as a way of organizing and storing data in a computer
so that it can used efficiently.
Data can be organized in different ways. The logical and mathematical model of a
particular organization of data is called as a data structure.
The choice of a particular data model depends on two considerations.
i) It must be rich enough in structure to mirror the actual relationships of the data in
the real world.
ii) The structure should be simple enough that one can effectively process the data
when necessary.
Types of Data Structure:
Data structures are divided into two types:
• Primitive data structures.
• Non-primitive data structures.
Primitive Data Structures are the basic data structures that directly operate upon the machine
instructions. They have different representations on different computers. Integers, floating point
numbers, character constants, string constants and pointers come under this category.
Non-primitive data structures are more complicated data structures and are derived from
primitive data structures. They emphasize on grouping same or different data items with
relationship between each data item. Arrays, lists and files come under this category. Figure 1
shows the classification of data structures.
Figure 1: Classification of Data Structures
Data Structure
Non-Linear Data Structure
trees, graphs
Linear Data Structures
lists, stack, queue
Non-Primitive Data Structures Primitive Data Structures
Eg: int, char, float
B. Madhuravani
DATA STRUCTURES UNIT-I
7. ABSTRACT DATA TYPE (ADT)
To manage the complexity of problems and the problem-solving process, computer scientists
use abstractions to allow them to focus on the “big picture” without getting lost in the details.
By creating models of the problem domain, we are able to utilize a better and more efficient
problem-solving process. These models allow us to describe the data that our algorithms will
manipulate in a much more consistent way with respect to the problem itself.
Earlier, we referred to procedural abstraction as a process that hides the details of a particular
function to allow the user or client to view it at a very high level. We now turn our attention to
a similar idea, that of data abstraction. An abstract data type, sometimes abbreviated ADT, is a
logical description of how we view the data and the operations that are allowed without regard
to how they will be implemented. This means that we are concerned only with what the data is
representing and not with how it will eventually be constructed. By providing this level of
abstraction, we are creating an encapsulation around the data. The idea is that by encapsulating
the details of the implementation, we are hiding them from the user’s view. This is called
information hiding.
Figure 2 shows a picture of what an abstract data type is and how it operates. The user interacts
with the interface, using the operations that have been specified by the abstract data type. The
abstract data type is the shell that the user interacts with. The implementation is hidden one
level deeper. The user is not concerned with the details of the implementation.
Figure 2: Abstract Data Type
The implementation of an abstract data type, often referred to as a data structure, will require
that we provide a physical view of the data using some collection of programming constructs
and primitive data types. As we discussed earlier, the separation of these two perspectives will
allow us to define the complex data models for our problems without giving any indication as
to the details of how the model will actually be built. This provides an implementation-
independent view of the data. Since there will usually be many different ways to implement an
abstract data type, this implementation independence allows the programmer to switch the
details of the implementation without changing the way the user of the data interacts with it.
The user can remain focused on the problem-solving process.
B. Madhuravani
DATA STRUCTURES UNIT-I
8. LINEAR LIST
List is basically the collection of elements arranged in a sequential manner. In memory we can
store the list in two ways: one way is we can store the elements in sequential memory locations.
That means we can store the list in arrays. The other way is we can use pointers or links to
associate elements sequentially. This is known as linked list.
Array
Array is a container which can hold fix number of items and these items should be of same
type. Most of the datastructure make use of array to implement their algorithms. Following
are important terms to understand the concepts of Array.
Element − Each item stored in an array is called an element.
Index − Each location of an element in an array has a numerical index which is used to
identify the element.
Array Representation
Arrays can be declared in various ways in different languages. For illustration, let's take C
array declaration.
Arrays can be declared in various ways in different languages. For illustration, let's take C
array declaration.
As per above shown illustration, following are the important points to be considered.
Index starts with 0.
Array length is 8 which means it can store 8 elements.
Each element can be accessed via its index. For example, we can fetch element at index
6 as 9.
B. Madhuravani
DATA STRUCTURES UNIT-I
Basic Operations
Following are the basic operations supported by an array.
Traverse – print all the array elements one by one.
Insertion – add an element at given index.
Deletion – delete an element at given index.
Search – search an element using given index or by value.
Update – update an element at given index.
Insertion Operation
Insert operation is to insert one or more data elements into an array. Based on the
requirement, new element can be added at the beginning, end or any given index of array.
Here, we see a practical implementation of insertion operation, where we add data at the end
of the array –
Algorithm:
Let Array is a linear unordered array of MAX elements.
1. Start
2. Set J=N
3. Set N = N+1
4. Repeat steps 5 and 6 while J >= K
5. Set LA[J+1] = LA[J]
6. Set J = J-1
7. Set LA[K] = ITEM
8. Stop
Deletion Operation
Deletion refers to removing an existing element from the array and re-organizing all elements
of an array.
Algorithm:
Consider LA is a linear array with N elements and K is a positive integer such that K<=N.
Below is the algorithm to delete an element available at the Kth position of LA.
1. Start
2. Set J=K
3. Repeat steps 4 and 5 while J < N
4. Set LA[J-1] = LA[J]
5. Set J = J+1
6. Set N = N-1
7. Stop
B. Madhuravani
DATA STRUCTURES UNIT-I
Search Operation
You can perform a search for array element based on its value or its index.
Algorithm:
Consider LA is a linear array with N elements and K is a positive integer such that K<=N.
Below is the algorithm to find an element with a value of ITEM using sequential search.
1. Start
2. Set J=0
3. Repeat steps 4 and 5 while J < N
4. IF LA[J] is equal ITEM THEN GOTO STEP 6
5. Set J = J +1
6. PRINT J, ITEM
7. Stop
Update Operation:
Update operation refers to updating an existing element from the array at a given index.
Algorithm
Consider LA is a linear array with N elements and K is a positive integer such that K<=N.
Below is the algorithm to update an element available at the Kth position of LA.
1. Start
2. Set LA[K-1] = ITEM
3. Stop
Linked Lists
The linked list is very different type of collection from an array. Using such lists, we
can store collections of information limited only by the total amount of memory that the OS
will allow us to use. Further more, there is no need to specify our needs in advance. The linked
list is very flexible dynamic data structure : items may be added to it or deleted from it at
will. A programmer need not worry about how many items a program will have to accommodate
in advance. This allows us to write robust programs which require much less maintenance.
The linked allocation has the following advantages:
1. Linked lists are dynamic data structures. i.e., they can grow or shrink during the execution
of a program.
2. Linked lists have efficient memory utilization. Here, memory is not pre-allocated. Memory
is allocated whenever it is required and it is de-allocated (removed) when it is no longer needed.
3. Insertion and Deletions are easier and efficient. Linked lists provide flexibility in inserting a
data item at a specified position and deletion of the data item from the given position.
4. Many complex applications can be easily carried out with linked lists.
B. Madhuravani
DATA STRUCTURES UNIT-I
The linked allocation has the following draw backs:
1. No direct access to a particular element.
2. Additional memory required for pointers.
Linked List Types
Linked list are of 4 types:
1. Single Linked List
2. Double Linked List
3. Circular Linked List
4. Circular Double Linked List
Comparison between array and linked list:
ARRAY
LINKED LIST
Size of an array is fixed
Size of a list is not fixed
Memory is allocated from stack
Memory is allocated from heap
It is necessary to specify the number of
elements during declaration (i.e., during
compile time).
It is not necessary to specify the number of
elements during declaration (i.e., memory is
allocated during run time).
It occupies less memory than a linked list
for the same number of elements.
It occupies more memory.
Inserting new elements at the front is
potentially expensive because existing
elements need to be shifted over to make
room.
Inserting a new element at any position can
be carried out easily.
Deleting an element from an array is not
possible.
Deleting an element is possible.
8.1 SINGLY LINKED LIST
A singly linked list, or simply a linked list, is a linear collection of data items. The linear
order is given by means of POINTERS. These types of lists are often referred to as linear
linked list.
* Each item in the list is called a node.
* Each node of the list has two fields:
1. Information- contains the item being stored in the list.
2. Next address- contains the address ti the next item in the list.
* The last node in the list contains NULL pointer to indicate that it is the end of the list.
8.1.1 Representation
Data Ptr Data NULL Data Ptr Data Ptr
B. Madhuravani
DATA STRUCTURES UNIT-I
8.1.2 Operations on Singly linked list:
Creation of a node
Insertions
Deletions
Traversing the list
Structure of a node:
//structure of a node
struct node
int data;
struct node *next;
*n,*head=NULL,*temp,*last;
Creation of a node:
//creation of a list
void create()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
if(head==NULL) //check whether list is empty
head=n;
temp=head;
last=temp;
else
B. Madhuravani
DATA STRUCTURES UNIT-I
last->next=n;
last=n;
Insertions: How do we place elements in the list: Usually, there are 4 cases we are inserted
in:
1. at the beginning
2. end of the list
3. after a given element
4. before a given element
B. Madhuravani
DATA STRUCTURES UNIT-I
case 1: at the beginning
//insert at the begining of a list
void insert_begin()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
n->next=head;
head=n;
B. Madhuravani
DATA STRUCTURES UNIT-I
case 2: end of the list
//insert at the end of a list
void insert_end()
int x;
temp=head;
if(temp==NULL)
flag=1;
else
while(temp->next!=NULL)
temp=temp->next;
n=(struct node*)malloc(sizeof(struct node));.//allocate memory for a node
n->data=val;
n->next=NULL;
if(flag==0)
temp->next=n;
else
head=n;
B. Madhuravani
DATA STRUCTURES UNIT-I
case 3: After a given element
//insert after a given element
void insert_after()
int x,key;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data after which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
temp=temp->next;
n->next=temp->next;
temp->next=n;
B. Madhuravani
DATA STRUCTURES UNIT-I
case 4: Before a given element
//insert before a given element
void insert_before()
int x,key;
struct node *prev;
n=(struct node*)malloc(sizeof(struct node));
printf("ENTER ELEMENT INTO THE LIST\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data before which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->next;
n->next=prev->next;
prev->next=n;
Deletions: Removing an element from the list, without destroying the integrity of the list
itself.
B. Madhuravani
DATA STRUCTURES UNIT-I
void delet()
int key;
struct node *prev;
printf("enter a data to remove\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->next;
prev->next=temp->next;
Traversing the list: Assuming we are given the pointer to the head of the list, how do we get
the end of the list.
//Display the list contents
void display()
temp=head;
printf("THE ELEMENTS IN THE LIST ARE..\n");
while(temp!=NULL)
printf("%d->",temp->data);
temp=temp->next;
B. Madhuravani
DATA STRUCTURES UNIT-I
C program to implement singly linked list
a// C Program to perform operations on Singly Linked List
#include<stdio.h>
#include<malloc.h>
//structure of a node
struct node
int data;
struct node *next;
*n,*head=NULL,*temp,*last;
//function declarations
void create();
void insert_begin();
void insert_end();
void insert_after();
void insert_before();
void delet();
void search();
void display();
int main()
int ch;
printf("MENU OPTIONS\n");
printf("1.CREATE A LIST\n");
printf("2.INSERT AN ELEMENT AT THE BEGINING\n");
printf("3.INSERT AN ELEMEMT AT THE END OF A LIST\n");
printf("4.INSERT AN ELEMENT AFTER A GIVEN NODE\n");
printf("5. INSERT AN ELEMENT BEFORE A GIVEN NODE\n");
printf("6. DELETE A GIVEN ELEMENT\n");
printf("7.SEARCH FOR A SPECIFIED ELEMENT\n");
printf("8.DISPLAY THE ELEMENTS IN THE LIST\n");
do
printf("ENTER YOUR CHOICE\n");
scanf("%d",&ch);
switch(ch)
case 1:
create();
break;
case 2:insert_begin();
break;
case 3:insert_end();
B. Madhuravani
DATA STRUCTURES UNIT-I
break;
case 4:insert_after();
break;
case 5:insert_before();
break;
case 6:delet();
break;
case 7:search();
break;
case 8:display();
break;
default:printf("INVALID CHOICE\n");
//switch
while(ch<=8);
return 0;
//main
//creation of a list
void create()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
if(head==NULL) //check whether list is empty
head=n;
temp=head;
last=temp;
else
last->next=n;
last=n;
//insert at the begining of a list
void insert_begin()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
B. Madhuravani
DATA STRUCTURES UNIT-I
n->next=head;
head=n;
//insert at the end of a list
void insert_end()
int x;
n=(struct node*)malloc(sizeof(struct node));.//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
last->next=n;
last=n;
//insert after a given element
void insert_after()
int x,key;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data after which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
temp=temp->next;
n->next=temp->next;
temp->next=n;
//insert before a given element
void insert_before()
int x,key;
B. Madhuravani
DATA STRUCTURES UNIT-I
struct node *prev;
n=(struct node*)malloc(sizeof(struct node));
printf("ENTER ELEMENT INTO THE LIST\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data before which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->next;
n->next=prev->next;
prev->next=n;
//Delete an element from the list
void delet()
int key;
struct node *prev;
printf("enter a data to remove\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->next;
prev->next=temp->next;
//Search for a given element in the list
void search()
temp=head;
int x,i=1;
printf("ENTER THE ELEMENT TO BE SEARCHED\n");
B. Madhuravani
DATA STRUCTURES UNIT-I
scanf("%d",&x);
while((temp!=NULL)&&(temp->data!=x))
temp=temp->next;
i++;
if(temp!=NULL)
printf("%d is FOUND AT POSITION %d\n",temp->data,i);
else
printf("ELEMENT NOT FOUND\n");
//Display the list contents
void display()
temp=head;
printf("THE ELEMENTS IN THE LIST ARE..\n");
while(temp!=NULL)
printf("%d->",temp->data);
temp=temp->next;
8.2 CIRCULARLY LINKED LIST
A circularly linked list, or simply circular list, is a linked list in which the last node is
always points to the first node. This type of list can be build just by replacing the NULL
pointer at the end of the list with a pointer which points to the first node. There is no first or
last node in the circular list.
8.2.1 Representation
8.2.2 Advantages and Disadvantages of Circular Linked List
Advantages:
1. If we are at a node, then we can go to any node. But in linear linked list it is not possible to
go to previous node.
2. It saves time when we have to go to the first node from the last node. It can be done in single
step because there is no need to traverse the in between nodes. But in double linked list, we will
have to go through in between nodes.
Disadvantages:
1. It is not easy to reverse the linked list.
B. Madhuravani
DATA STRUCTURES UNIT-I
2. If proper care is not taken, then the problem of infinite loop can occur.
3. If we at a node and go back to the previous node, then we can not do it in single step. Instead
we have to complete the entire circle by going through the in between nodes and then we will
reach the required node.
8.2.3 Operations on Circular linked list
Creation of a node
Insertions
Deletions
Traversing the list
//C Program to create circularly linked list and perform operations
#include<stdio.h>
#include<stdlib.h>
struct node
int data;
struct node *link;
*cur,*prev,*temp,*last,*first=NULL;
void create();
void display();
void insert_begin();
void insert_after();
void insert_before();
void del_begin();
void del();
int main()
int ch=0;
while(ch<=7)
printf("enter ur choice\n");
scanf("%d",&ch);
switch(ch)
case 1:create();
break;
case 2:insert_begin();
break;
case 3:insert_after();
break;
case 4:insert_before();
break;
case 5:del_begin();
break;
case 6:del();
break;
case 7:display();
B. Madhuravani
DATA STRUCTURES UNIT-I
break;
//switch
//while
//main
void create()
cur=(struct node*)malloc(sizeof(struct node));
printf("enter data\n");
scanf("%d",&cur->data);
cur->link=NULL;
if(first==NULL)
first=cur;
last=cur;
else
last->link=cur;
last=cur;
last->link=first;
//create
void insert_begin()
cur=(struct node*)malloc(sizeof(struct node));
printf("enter data\n");
scanf("%d",&cur->data);
last->link=cur;
cur->link=first;
first=cur;
//insert_begin()
void insert_after()
int key;
cur=(struct node*)malloc(sizeof(struct node));
printf("enter data\n");
scanf("%d",&cur->data);
cur->link=NULL;
printf("enter element after which u want to insert\n");
scanf("%d",&key);
temp=first;
while(temp!=NULL)
if(temp->data==key)
break;
else
temp=temp->link;
B. Madhuravani
DATA STRUCTURES UNIT-I
cur->link=temp->link;
temp->link=cur;
//insert_after
void insert_before()
int key;
cur=(struct node*)malloc(sizeof(struct node));
printf("enter data\n");
scanf("%d",&cur->data);
cur->link=NULL;
printf("Enter before which u want to insert\n");
scanf("%d",&key);
temp=first;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->link;
//else
//while
cur->link=temp;
prev->link=cur;
void del_begin()
temp=first;
first=first->link;
last->link=first;
free(temp);
void del()
int key;
temp=first;
printf("enter data to delete");
scanf("%d",&key);
while(temp!=NULL)
if(temp->data==key)
break;
else
prev=temp;
temp=temp->link;
//else
prev->link=temp->link;
B. Madhuravani
DATA STRUCTURES UNIT-I
free(temp);
//del
void display()
temp=first;
do
printf("%d\t",temp->data);
temp=temp->link;
while(temp!=first);
8.3 DOUBLY LINKED LIST
A singly linked list has the disadvantage that we can only traverse it in one direction. Many
applications require searching backwards and forwards through sections of a list. A useful
refinement that can be made to the singly linked list is to create a doubly linked list. The
distinction made between the two list types is that while singly linked list have pointers going
in one direction, doubly linked list have pointer both to the next and to the previous element in
the list.
8.3.1 Representation
The main advantage of a doubly linked list is that, they permit traversing or searching of the
list in both directions.
8.3.2 Advantages and Disadvantages of Double Linked List
Advantages:
1. We can traverse in both directions i.e. from starting to end and as well as from end to
starting.
2. It is easy to reverse the linked list.
3. If we are at a node, then we can go to any node. But in linear linked list, it is not possible to
reach the previous node.
Disadvantages:
1. It requires more space per space per node because one extra field is required for pointer to
previous node.
Lptr Info Rptr Lptr Info Rptr Lptr Info Rptr
B. Madhuravani
DATA STRUCTURES UNIT-I
2. Insertion and deletion take more time than linear linked list because more pointer
operations are required than linear linked list.
8.3.3 Operations on Doubly linked list
Creation of a node
Insertions
Deletions
Traversing the list
Creation of a node:
Struct node
int data;
node *next;
node *prev;
;
Insertions: How do we place elements in the list ?
Deletions: Removing an element from the list, without destroying the integrity of the list
itself.
Traversing the list: Assuming we are given the pointer to the head of the list, how do we get
the end of the list.
/* C program to perform various operations on doubly linked list*/
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
//structure of a node
struct node
int data;
struct node *next,*prev;
*n,*head=NULL,*temp,*last;
//function declarations
void create();
void insert_begin();
void insert_end();
void insert_after();
void insert_before();
B. Madhuravani
DATA STRUCTURES UNIT-I
void delet();
void search();
void display();
void main()
int ch;
clrscr();
printf("MENU OPTIONS\n");
printf("1.CREATE A LIST\n");
printf("2.INSERT AN ELEMENT AT THE BEGINING\n");
printf("3.INSERT AN ELEMEMT AT THE END OF A LIST\n");
printf("4.INSERT AN ELEMENT AFTER A GIVEN NODE\n");
printf("5. INSERT AN ELEMENT BEFORE A GIVEN NODE\n");
printf("6. DELETE A GIVEN ELEMENT\n");
printf("7.SEARCH FOR A SPECIFIED ELEMENT\n");
printf("8.DISPLAY THE ELEMENTS IN THE LIST\n");
do
printf("ENTER YOUR CHOICE\n");
scanf("%d",&ch);
switch(ch)
case 1:
create();
break;
case 2:insert_begin();
break;
case 3:insert_end();
break;
case 4:insert_after();
break;
case 5:insert_before();
break;
case 6:delet();
break;
case 7:search();
break;
case 8:display();
break;
default:printf("INVALID CHOICE\n");
//switch
while(ch<=8);
getch();
//main
B. Madhuravani
DATA STRUCTURES UNIT-I
//creation of a list
void create()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
n->prev=NULL;
if(head==NULL) //check whether list is empty
head=n;
temp=head;
last=temp;
else
last->next=n;
n->prev=last;
last=n;
//insert at the begining of a list
void insert_begin()
int x;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
if(head==NULL)//check whether list is empty
head=n;
temp=head;
last=temp;
else
n->next=head;
head->prev=n;
head=n;
B. Madhuravani
DATA STRUCTURES UNIT-I
//insert at the end of a list
void insert_end()
int x;
n=(struct node*)malloc(sizeof(struct node));.//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
if(head==NULL)
head=n;
temp=head;
last=temp;
else
last->next=n;
n->prev=last;
last=n;
//insert after a given element
void insert_after()
int x,key;
n=(struct node*)malloc(sizeof(struct node));//allocate memory for a node
printf("ENTER ELEMENT\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data after which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
temp=temp->next;
n->next=temp->next;
temp->next->prev=n;
temp->next=n;
n->prev=temp;
B. Madhuravani
DATA STRUCTURES UNIT-I
//insert before a given element
void insert_before()
int x,key;
struct node *prev1;
n=(struct node*)malloc(sizeof(struct node));
printf("ENTER ELEMENT INTO THE LIST\n");
scanf("%d",&x);
n->data=x;
n->next=NULL;
printf("enter a data before which u want to insert a node\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev1=temp;
temp=temp->next;
n->next=prev1->next;
prev1->next->prev=n;
prev1->next=n;
n->prev=prev1;
//Delete an element from the list
void delet()
int key;
struct node *prev1;
printf("enter a data to remove\n");
scanf("%d",&key);
temp=head;
while(temp!=NULL)
if(temp->data==key)
break;
else
prev1=temp;
temp=temp->next;
prev1->next=temp->next;
temp->next->prev=prev1;
B. Madhuravani
DATA STRUCTURES UNIT-I
//Search for a given element in the list
void search()
int x,i=1;
temp=head;
printf("ENTER THE ELEMENT TO BE SEARCHED\n");
scanf("%d",&x);
while((temp!=NULL)&&(temp->data!=x))
temp=temp->next;
i++;
if(temp!=NULL)
printf("%d is FOUND AT POSITION %d\n",temp->data,i);
else
printf("ELEMENT NOT FOUND\n");
//Display the list contents
void display()
temp=head;
printf("THE ELEMENTS IN THE LIST ARE..\n");
while(temp!=NULL)
printf("%d->",temp->data);
temp=temp->next;
B. Madhuravani
DATA STRUCTURES UNIT-I
9. APPLICATIONS OF LINKED LIST
1. Linked lists are used to represent and manipulate polynomial. Polynomials are expression
containing terms with non zero coefficient and exponents. For example:
P(x) = a0 Xn + a1 Xn-1 + …… + an-1 X + an
2. Represent very large numbers and operations of the large number such as addition,
multiplication and division.
3. Linked lists are to implement stack, queue, trees and graphs.
4. Implement the symbol table in compiler construction
Previous Question Paper Questions
1. Define Data Structure. [June ‘16]
2. Explain Big-oh, Omega & Theta Notations. [June ‘16]
3. Write a C program to read a given a linked list and two integers M and N. Traverse the
linked list such that you retain M nodes then delete next N nodes, continue the same
until end of the linked list. (Example: Input: M = 2, N = 2, Linked List: 1->2->3->4->5-
>6->7->8 : Output: Linked List: 1->2->5->6). [June ‘16]
4. Write a C program to implement a singly linked list. [June ‘16]
5. What are the advantages and disadvantages of doubly linked list over singly linked list?
Explain the applications of doubly linked lists. [June ‘16]
6. What are the advantages and disadvantages of a linked lists. [July ‘16]
7. Write the Double linked list insertion algorithm. [July ‘16]
8. Write a program in C to implement doubly linked List. [July ‘16]
QUESTION BANK
SHORT ANSWER QUESTIONS
1. Define the term algorithm and state the criteria the algorithm should satisfy?
2. Define recursive algorithm?
3. Differentiate between recursive and iterative algorithms?
4. Define asymptotic notations: big ‘Oh’, omega and theta?
5. Describe best case, average case and worst case efficiency of an algorithm>
6. How do you measure the algorithm running time?
7. Describe the role of time complexity and space complexity in measuring the
performance of a program?
8. Define the term data abstraction?
B. Madhuravani
DATA STRUCTURES UNIT-I
9. Define data structure?
10. List linear and non linear data structures?
11. List out the operations performed in the Linear Data Structure?
12. List out any four applications of data structure?
13. Define Linked List?
14. State different types of Linked List?
15. List the basic operations carried out in a linked list?
16. List the advantages and disadvantages of Linked List.
17. Define doubly linked list?
18. List the advantages and disadvantages of Doubly Linked List.
19. Define Circular linked list.
20. List the advantages and disadvantages of Circular Linked List.
LONG ANSWER QUESTIONS
1. Discuss various asymptotic notations used for best, average and worst case analysis of
algorithms.
2. Explain performance analysis in detail.
3. Define recursion. Explain with Fibonacci series, factorial and Towers of Hanoi.
4. Explain time and space complexities in detail.
5. Explain different operations on singly linked list.
6. Explain concatenation of two singly linked list.
7. Explain circular linked list operations.
8. Explain doubly linked list operations.
9. Explain the following operations in a DLL a)insertion b)Deletion c)Reverse the list
10. Write an algorithm to insert and delete a key in a CLL.
11. Write a program to insert an element in between two nodes in a DLL.
12. Explain how to create circular linked list and insert nodes at end.
13. F(n)=3n2-n+4 show that F(n)=O(n2)
14. Given a singly linked list with each node containing either 0, 1 or 2. Write code to sort
the list.
Input: 1->1->2->0->2->0->1->0
Output:0->0->0->1->1->1->2->2
15. Write a C program to read a given a linked list and two integers M and N. Traverse the
linked list such that you retain M nodes then delete next N nodes, continue the same
until end of the linked list. (Example: Input: M = 2, N = 2, Linked List: 1->2->3->4->5-
>6->7->8 : Output: Linked List: 1->2->5->6).
16. Given two linked list in a way such that the resultant must contain the elements
alternatively from one list to other list.
Input: LL1 1->2->3->4
LL2 5->6->7
Output: 1->5->2->6->3->7->4
17. Write a program to remove duplicate values from a double linked list.
B. Madhuravani
DATA STRUCTURES UNIT-I
18. Write a C program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) Display the contents of the above list in Reverse.
19. Write a C program that uses functions to perform the following:
a) Create two singly linked list of integers.
b) Compare the above two lists.
20. Write a C program that uses functions to perform the following:
a) Create two sorted singly linked list of integers.
b) Merge the above two lists.
c) Display the contents after merging.
21. Write a C program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) Display the node at a given position from above list.
22. Write a C program that uses functions to perform the following:
a) Create a sorted singly linked list of integers.
b) Delete duplicate-value nodes from above list.
c) Display the contents of the above list after deletion.
23. Write a C program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) Detect cycles from above list.
24. Write a C program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) swap to swap every two nodes from above list.
e.g: 1->2- >3->4- >5->6 should become 2->1- >4->3- >6->5
25.Write a C program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) Sort the list
c) Display the contents of the above list after sorting.
26. Write “C” functions to compute the following operations on polynomials represented
as singly connected linked list of nonzero terms.
a).Creation of a polynomial.
b) Addition of two polynomials.