Professional Documents
Culture Documents
BY
Kaivan Shah
This book is sold subject to the condition that it shall not, by the way of trade
or otherwise, be lent, resold, hired out, or otherwise circulated without the
publisher's prior written consent in any form of building or cover other than
which it is published and without a similar condition including this condition
being imposed on the subsequent purchaser and without limiting the rights
under copyright reserved above.
This edition is for sale in India only. Sale and purchase of this book outside
of this country is unauthorized by the publisher.
Published by:
Ques10
Shop No. 18, Tapovan Arcade, Nahur (W), Mumbai - 400078.
Email: helpdesk@ques10.com
Website: www.ques10.com
Preface
People say, "Don't judge a book by its cover". But don't we?
But, while studying we do notice that they are not up to the mark. No clear
explanation, tons of mistakes, tough sentences.. you know what we are
talking about. That's why we have made Ques10 books.
We thought what if we can write books which are concise and to-the-point?
That’s pretty much it. We hope you like our books and benefit from them.
Team Ques10
Syllabus
01 Introduction to Data Structures
03 Linked List
04 Trees
05 Graphs
Introduction, Bubble Sort, Insertion Sort, Merge Sort, Quick Sort. Linear
Search, Binary Search, Hashing – Concept, Hash Functions, Collision
Handling Techniques.
V0514th20201
Chapter 1
7. Lists are further sub divided into Linear and Non Linear Data structure.
1. Tree: It has a set of nodes which have data and pointers or references.
The pointers point to the children nodes of the node. The constraint is
that no reference is duplicated and no node points to the root.
1. Graph: It’s a collection of a set of vertices V and a set of edges E. Each
edge E is a pair (v, w) where v and w are elements of V (i.e. they are
vertices).
/ Abstract Datatype
Chap 1
1. Abstract Data type (ADT) is a type (or class) for objects whose behavior
is defined by a set of value and a set of operations
2. The definition of ADT only mentions what operations are to be
performed but not how these operations will be implemented
3. It does not specify how data will be organized in memory.
4. Also it does not specify what algorithms will be used for
5. ADT provides only the essentials information to the user and hides the
details of its implementation and hence it is called abstract.
6. Examples of ADT
FILE *fp;
Stack as ADT
Queue Program
Stack using Linked List
Recursion as an application of stack
/ Stack as ADT
Chap 2
5. Where variable SIZE is used to specify the length of stack and its
declared as constant
#include<stdio.h>
#include<conio.h>
#define max 5
typedef struct Queue
{
int r,f;
int data[max];
}queue;
void initialize(queue *p);
int empty (queue *p);
int full(queue *p);
void enqueue(queue *p,int x);
int dequeue(queue *p);
void printQueue(queue *p);
void main()
{
queue q;
int op,x;
initialize(&q);
do
{
printf("\n 1. INSERT \n 2. DELETE \n 3. PRINT \n
4. QUIT") ;
printf("\n Enter your choice");
scanf("%d",&op);
switch(op)
{
case 1 : printf("\n Enter a number");
scanf("%d",&x);
if(!full(&q))
{
enqueue(&q,x);
}
else
{
printf("\n QUEUE IS FULL");
}
break;
case 2 : if(!empty(&q))
{
x=dequeue(&q);
printf("\n DELETED ELEMENT IS %d",x);
}
else
{
printf("\n QUEUE IS EMPTY");
}
break;
case 3 : if(!empty(&q))
{
printQueue(&q);
}
else
{
printf("\n QUEUE IS EMPTY");
}
break;
default : printf("\n INVALID OPTION ");
}
}while(op!=4);
}
void initialize(queue *p)
{
p->r=-1;
p->f=-1;
}
int empty(queue *p)
{
if(p->r==-1)
{
return (1);
}
else
{
return(0);
}
}
int full(queue *p)
{
if(p->r==max-1)
{
return(1);
}
else
{
return(0);
}
}
void enqueue(queue *p,int x)
{
if(p->r==-1)
{
p->r=p->f=0;
p->data[p->r]=x;
}
else
{
p->r=p->r+1;
p->data[p->r]=x ;
}
}
int dequeue(queue *p)
{
int t;
t=p->data[p->f];
if(p->f==p->r)
{
p->f=-1;
p->r=-1;
}
else
{
p->f=p->f=+1;
}
return(t);
}
void printQueue(queue *p)
{
int i;
for(i=p->f;i<=p->r;i++)
{
printf(" %d ",p->data[i]);
}
}
/ Queue Program
Chap 2
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *ptr;
}*front,*rear,*temp,*front1;
int frontelement();
void enq(int data);
void deq();
void empty();
void display();
void create();
void queuesize();
int count = 0;
void main()
{
int no, ch, e;
printf("\n 1 - Enque");
printf("\n 2 - Deque");
printf("\n 3 - Front element");
printf("\n 4 - Empty");
printf("\n 5 - Exit");
printf("\n 6 - Display");
printf("\n 7 - Queue size");
create();
while (1)
{
printf("\n Enter choice : ");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("Enter data : ");
scanf("%d", &no);
enq(no);
break;
case 2:
deq();
break;
case 3:
e = frontelement();
if (e != 0)
printf("Front element : %d", e);
else
printf("\n No front element in Queue as
queue is empty");
break;
case 4:
empty();
break;
case 5:
exit(0);
case 6:
display();
break;
case 7:
queuesize();
break;
default:
printf("Wrong choice, Please enter correct
choice ");
break;
}
}
}
/* Create an empty queue */
void create()
{
front = rear = NULL;
}
/* Returns queue size */
void queuesize()
{
printf("\n Queue size : %d", count);
}
/* Enqueing the queue */
void enq(int data)
{
if (rear == NULL)
{
rear = (struct node *)malloc(1*sizeof(struct node));
rear->ptr = NULL;
rear->info = data;
front = rear;
}
else
{
temp=(struct node *)malloc(1*sizeof(struct node));
rear->ptr = temp;
temp->info = data;
temp->ptr = NULL;
rear = temp;
}
count++;
}
/* Displaying the queue elements */
void display()
{
front1 = front;
if ((front1 == NULL) && (rear == NULL))
{
printf("Queue is empty");
return;
}
while (front1 != rear)
{
printf("%d ", front1->info);
front1 = front1->ptr;
}
if (front1 == rear)
printf("%d", front1->info);
}
/* Dequeing the queue */
void deq()
{
front1 = front;
if (front1 == NULL)
{
printf("\n Error: Trying to display elements from
empty queue");
return;
}
else
if (front1->ptr != NULL)
{
front1 = front1->ptr;
printf("\n Dequed value : %d", front->info);
free(front);
front = front1;
}
else
{
printf("\n Dequed value : %d", front->info);
free(front);
front = NULL;
rear = NULL;
}
count--;
}
/* Returns the front element of queue */
int frontelement()
{
if ((front != NULL) && (rear != NULL))
return(front->info);
else
return 0;
}
/* Display if queue is empty or not */
void empty()
{
if ((front == NULL) && (rear == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
#include <stdio.h>
#include <stdlib.h>
struct node
{
int info;
struct node *ptr;
}*top,*top1,*temp;
int topelement();
void push(int data);
void pop();
void empty();
void display();
void destroy();
void stack_count();
void create();
int count = 0;
void main()
{
int no, ch, e;
printf("\n 1 - Push");
printf("\n 2 - Pop");
printf("\n 3 - Top");
printf("\n 4 - Empty");
printf("\n 5 - Exit");
printf("\n 6 - Dipslay");
printf("\n 7 - Stack Count");
printf("\n 8 - Destroy stack");
create();
while (1)
{
printf("\n Enter choice : ");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("Enter data : ");
scanf("%d", &no);
push(no);
break;
case 2:
pop();
break;
case 3:
if (top == NULL)
printf("No elements in stack");
else
{
e = topelement();
printf("\n Top element : %d", e);
}
break;
case 4:
empty();
break;
case 5:
exit(0);
case 6:
display();
break;
case 7:
stack_count();
break;
case 8:
destroy();
break;
default :
printf(" Wrong choice, Please enter correct choice
");
break;
}
}
}
/* Create empty stack */
void create()
{
top = NULL;
}
/* Count stack elements */
void stack_count()
{
printf("\n No. of elements in stack : %d", count);
}
/* Push data into stack */
void push(int data)
{
if (top == NULL)
{
top =(struct node *)malloc(1*sizeof(struct node));
top->ptr = NULL;
top->info = data;
}
else
{
temp =(struct node *)malloc(1*sizeof(struct node));
temp->ptr = top;
temp->info = data;
top = temp;
}
count++;
}
/* Display stack elements */
void display()
{
top1 = top;
if (top1 == NULL)
{
printf("Stack is empty");
return;
}
while (top1 != NULL)
{
printf("%d ", top1->info);
top1 = top1->ptr;
}
}
/* Pop Operation on stack */
void pop()
{
top1 = top;
if (top1 == NULL)
{
printf("\n Error : Trying to pop from empty stack");
return;
}
else
top1 = top1->ptr;
printf("\n Popped value : %d", top->info);
free(top);
top = top1;
count--;
}
/* Return top element */
int topelement()
{
return(top->info);
}
/* Check if stack is empty or not */
void empty()
{
if (top == NULL)
printf("\n Stack is empty");
else
printf("\n Stack is not empty with %d elements", count);
}
/* Destroy entire stack */
void destroy()
{
top1 = top;
while (top1 != NULL)
{
top1 = top->ptr;
free(top);
top = top1;
top1 = top1->ptr;
}
free(top1);
top = NULL;
printf("\n All stack elements destroyed");
count = 0;
}
2.Following are the points in favour of Linked Lists.
a. The size of the arrays is fixed: So we must know the upper limit on the
number of elements in advance. Also, generally, the allocated memory is
equal to the upper limit irrespective of the usage, and in practical uses, upper
limit is rarely reached.
c. For example, suppose we maintain a sorted list of IDs in an array id[]. id[]
= [1000, 1010, 1050, 2000, 2040, …..]. And if we want to insert a new ID
1005, then to maintain the sorted order, we have to move all the elements
after 1000 (excluding 1000).
d. Deletion is also expensive with arrays until unless some special techniques
are used. For example, to delete 1010 in id[], everything after 1010 has to be
moved.
6. Also, as a function calls to another function, first its arguments, then the
return address and finally space for local variables is pushed onto the
stack.
7. Recursion is extremely useful and extensively used because many
problems are elegantly specified or solved in a recursive way.
Linked List
Content
1. The size of the arrays is fixed: So we must know the upper limit on
the number of elements in advance. Also, generally, the allocated
memory is equal to the upper limit irrespective of the usage, and in
practical uses, upper limit is rarely reached.
2. Inserting a new element in an array of elements is expensive,
because room has to be created for the new elements and to create
room existing elements have to shifted.
3. For example, suppose we maintain a sorted list of IDs in an array
id[]. id[] = [1000, 1010, 1050, 2000, 2040, …..]. And if we want to
insert a new ID 1005, then to maintain the sorted order, we have to
move all the elements after 1000 (excluding 1000).
4. Deletion is also expensive with arrays until unless some special
techniques are used. For example, to delete 1010 in id[], everything
after 1010 has to be moved.
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
typedef struct node
{
int data;
struct node* next;
}node;
node* create(int);
void print(node*);
int count(node*);
node* insertB(node*,int);
node* insertM(node*,int);
node* insertE(node*,int);
node* del(node*);
void main()
{
node *HEAD;
int n,number,ch,value;
clrscr();
printf("\n Enter no. of Item");
scanf("%d",&n);
HEAD=create(n);
do
{
printf("\n 1.Insert at Begining \n 2.Insert after a
specified value \n 3.Insert at End \n 4.DELETE \n 5.Display \n
6.Count \n 7.Exit \n");
printf("Enter your choice \n");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertB(HEAD,value);
break;
case 2:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertM(HEAD,value);
break;
case 3:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertE(HEAD,value);
break;
case 4:
HEAD=del(HEAD);
break;
case 5:
print(HEAD);
break;
case 6:
number = count(HEAD);
printf("Number of Nodes = %d",number);
break;
case 7:
printf("Exit");
break;
default:
printf("Invalid input \n");
}
}
while(ch!=7);
getch();
}
node* create(int n)
{
node *head,*P;
int i;
head=(node*)malloc(sizeof(node));
head->next=NULL;
printf("Enter your Data \n");
scanf("%d",(&head->data));
P=head;
for(i=1;i<n;i++)
{
P->next=(node*)malloc(sizeof(node));
P=P->next;
printf("Enter your Data \n");
scanf("%d",(&P->data));
P->next=NULL;
}
return(head);
}
void print(node *P)
{
while(P!=NULL)
{
printf("--%d--",P->data);
P=P->next;
}
}
int count(node *P)
{
int i=0;
while(P!=NULL)
{
P=P->next;
i++;
}
return(i);
}
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct Dnode
{
int data;
struct Dnode* next;
struct Dnode* prev;
}Dnode;
Dnode* create(int);
void print(Dnode*);
int count(Dnode*);
Dnode* insertB(Dnode*,int);
Dnode* insertM(Dnode*,int);
Dnode* insertE(Dnode*,int);
Dnode* del(Dnode*);
void main()
{
Dnode *HEAD;
int n,number,ch,value;
clrscr();
printf("\n Enter no. of Item");
scanf("%d",&n);
HEAD=create(n);
do
{
printf("\n 1.Insert at Begining \n 2.Insert after a
specified value \n 3.Insert at End \n 4.DELETE \n 5.Display \n
6.Count \n 7.Exit \n");
printf("Enter your choice \n");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertB(HEAD,value);
break;
case 2:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertM(HEAD,value);
break;
case 3:
printf("Enter the value to be inserted");
scanf("%d",&value);
HEAD = insertE(HEAD,value);
break;
case 4:
HEAD=del(HEAD);
break;
case 5:
print(HEAD);
break;
case 6:
number = count(HEAD);
printf("Number of Nodes = %d",number);
break;
case 7:
printf("Exit");
break;
default:
printf("Invalid input \n");
}
}
while(ch!=7);
getch();
}
Dnode* create(int n)
{
Dnode *head,*P,*Q;
int i;
head=(Dnode*)malloc(sizeof(Dnode));
head->next=NULL;
printf("Enter your Data \n");
scanf("%d",(&head->data));
P=head;
for(i=1;i<n;i++)
{
P->next=(Dnode*)malloc(sizeof(Dnode));
(P->next)->prev = P;
P=P->next;
printf("Enter your Data \n");
scanf("%d",(&P->data));
P->next=NULL;
}
return(head);
}
void print(Dnode *P)
{
while(P!=NULL)
{
printf("--%d--",P->data);
P=P->next;
}
}
int count(Dnode *P)
{
int i=0;
while(P!=NULL)
{
P=P->next;
i++;
}
return(i);
}
Dnode* insertB(Dnode* HEAD,int x)
{
Dnode* p;
p=(Dnode*)malloc(sizeof(Dnode));
p->data = x;
if(HEAD==NULL)
{
HEAD=p;
HEAD->next=NULL;
}
else
{
p->next=HEAD;
HEAD=p;
}
HEAD->prev=NULL;
return(HEAD);
}
Dnode* insertM(Dnode* HEAD,int x)
{
Dnode* p,*q;
int y;
p=(Dnode*)malloc(sizeof(Dnode));
p->data = x;
p->next = NULL;
p->prev = NULL;
printf("Insert after which number \n");
scanf("%d",&y);
q=HEAD;
while(q!=NULL && q->data!=y)
{
q=q->next;
}
if(q!=NULL)
{
p->next = q->next;
p->prev = q;
(p->next)->prev = p;
q->next = p;
}
else
{
printf("Data not found \n");
}
return(HEAD);
}
Dnode* insertE(Dnode* HEAD,int x)
{
Dnode* p,*q;
p=(Dnode*)malloc(sizeof(Dnode));
p->data = x;
p->next = NULL;
p->prev = NULL;
if(HEAD==NULL)
{
return(p);
}
q=HEAD;
while(q->next!=NULL)
{
q=q->next;
}
q->next = p;
p->prev = q;
return(HEAD);
}
Dnode* del(Dnode * HEAD)
{
Dnode *p,*q;
int e;
if(HEAD==NULL)
{
printf("Empty LL \n");
return(HEAD);
}
printf("Enter element to be deleted \n");
scanf("%d",&e);
flushall();
p=HEAD;
if(HEAD->data==e)
{
HEAD = HEAD->next;
free(p);
return(HEAD);
}
1. The biggest integer that we can store in a variable of the type int is
231 - 1 on 32-but CPU.If the value becomes too large, Java saves
only the low order 32 (or 64 for longs) bits and throws the rest
away.
2. In real life applications we need to deal with integers that are larger
than 64 bits (the size of a long). To manipulate with such big
numbers, we will be using a linked list data structure
3. The following numbers can also be expressed as below:- 937 =
910^2 + 310^1 + 710^0 and 2011 = 210^3 + 010^2 + 110^1 +
1*10^0
4. Now, if we replace a decimal base 10 by a character, say 'x', we
obtain a univariate polynomial, such as 0.45 - 1.89 x2 + 3.4 x5 + 9
x16. This can be saved using linked list as follows
7. The alloc_frame function retrieves the number of a free frame from a list
of available frames.
8. Given a specific page, this number is placed in the page table to indicate
in which physical frame the page is to reside. The free_frame function
accepts a frame number and places it back into the list of available
frames once a page has been removed from physical memory.
9. Both functions assume that before either function is called, the operating
system has inserted into the list all frames that it wishes to make
available. The example for circular lists later in this chapter addresses
what happens when allot frame is called and the list is empty.
10. A linked list is a good way to manage frames because frame allocation
involves frequent insertions and deletions, and these operations are
performed at the head of the list. The runtime complexity of both
alloc_fiame and free_frame is O(1) because the two functions simply
call list_rem_next and list_ins_next respectively, which are both O(1)
operations.
Chapter 4
Trees
Content
1. if there is a left-child, then the data in the left-child is less than the data
in the root,
2. if there is a right-child, then the data in the right-child is no less than the
data in the root, and every sub-tree is a binary search tree. // algorithm to
implement insertion operation in BST
Delete operation on binary search tree is more complicated, then add and
search. Basically, in can be divided into two stages:
Now, let's see more detailed description of a remove algorithm. First stage is
identical to algorithm for lookup, except we should track the parent of the
current node. Second part is trickier. There are three cases, which are
described below.
It this case, node is cut from the tree and algorithm links single child
(with it's subtree) directly to the parent of the removed node. Example.
Remove 18 from a BST.
1. Node to be deleted has two children.
This is the most complex case. To solve it, let us see one useful BST
property first. We are going to use the idea, that the same set of values
may be represented as different binary-search trees. For example those
BSTs:
contains the same values {5, 19, 21, 25}. To transform first tree into second
one, we can do following:
choose minimum element from the right subtree (19 in the example);
replace 5 by 19;
hang 5 as a left child.
The same approach can be utilized to remove a node, which has two children:
Postorder “INOFMAINOTR”
Since, R is the last element in the post order sequence, R will be the root.
Elements to the left of R will be a part of left sub tree and the elements to the
right of R will be a part of right sub tree.
Further, F is the last element of post Order sequence in the left sub tree.
Elements before F i.e. I and N will be a part of left sub tree and O will be a
part of right sub tree.
This process can be continued for the remaining elements to obtain the
resultant binary tree.
Example
/ Threaded Binary Tree
Chap 4
1. In a linked list representation of binary trees, there are more null links
than the node links. Such null links are replaced by pointers called as
threads, such a tree is called as Threaded Binary Tree.
2. A left null link of a node is replaced with the address of its in-order
predecessor.
3. A right null link of a node is replaced with the address of its in-order
successor.
4. Example
b. Double threaded: each node is threaded towards both(left & right)' the
in-order predecessor and' successor.
1. To traverse a binary tree means to visit each node of the tree exactly
once in a systematic fashion.
B. In-order Traversal
C. Post-order Traversal
/ Huffman Coding
Chap 4
2. No symbols are assigned codes and every new symbol is treated as a leaf
node with the same weight.
3. As new symbols are added, the tree is also updated such that the updated
tree is also a Huffman tree.
4. The first symbol is written on the output stream as it is. This symbol is
then added to the tree and a code is assigned to it.
5. The next time this symbol occurs, its current code is written on the
output stream and its frequency is incremented by
6.
7. Each time the symbols are processed, it has to be checked whether the
tree satisfies the Huffman properties.
1. The process of updating the tree starts always at the current node which
is a leaf S with f as it frequency of occurrence.
• Compare S to its successors in the tree from left to right and bottom to top.
If the immediate successor has frequency (f + 1) or more then the nodes are
still in sorted order and swapping is not required. Otherwise some successors
of S have identical frequency f or smaller frequency. In such a case S should
be swapped with the last node in this group.
• If S becomes the root then the process stops otherwise the process repeats
with the parent of node S.
Drawbacks of Adaptive Huffman coding:
Count overflow:
• The frequency counts are accumulated and this field can overflow.
Normally the width of this field is 16 bits and can store a count up to 65535.
• When the maximum count limit is reached, all the weights are revealed with
an integer division by 2.
Code overflow:
• Code overflow when many symbols are added to the tree and the tree grows
longer.
• The compressor has to find out the code for an input symbol S in the tree by
linear search method.
• If S is found in the tree, the compressor moves from node S back to root
thus building the code bit by bit.
• When the tree gets longer, the codes get longer and if the field size is
exceeded, the program malfunctions.
To overcome this inefficiency we use adaptive Huffman coding, the same can
be illustrated with the help of following example:
Consider a source that puts out iid letters from the alphabet A = {a1, a2, a3}
with the probability model P(a1) = 0.8, P(a2) = 0.02, and P(a3) = 0.18. The
entropy for this source is 0.816 bits/symbol. A Huffman code for this source
is shown in Table below
LetterCodeword
a1 0
a2 11
a3 10
The average length for this code is 1.2 bits/symbol. The difference between
the average code length and the entropy, or the redundancy, for this code is
0.384 bits/symbol, which is 47% of the entropy. This means that to code this
sequence we would need 47% more bits than the minimum required.
Now for the source described in the above example, instead of generating a
codeword for every symbol, we will generate a codeword for every two
symbols. If we look at the source sequence two at a time, the number of
possible symbol pairs, or size of the extended alphabet, is 32 = 9. The
extended alphabet, probability model, and Huffman code for this example are
shown in Table below
LetterProbability Code
a1a1 0.64 0
a1a2 0.016 10101
a1a3 0.144 11
a2a1 0.016 10100
a2a2 0.0004 10100101
a2a3 0.0036 1010011
a3a1 0.1440 100
a3a2 0.0036 10100100
a3a3 0.0324 10100
The average codeword length for this extended code is 1.7228 bits/symbol.
However, each symbol in the extended alphabet corresponds to two symbols
from the original alphabet.
This redundancy is about 0.045 bits/symbol, which is only about 5.5% of the
entropy.
Consider the length of the window is 13 in which the size of search buffer is
7.
Size of look ahead buffer is 6. It is assumed that contents of search buffer are
already encoded.
Offset (o) = 6
Length (l) = 1
Code = c(r)
Length (l) = 1
Code = c(a)
Offset (o) = 5
Length (l) = 1 + 1 =2
Now, in this case the actual length l = 2 because ‘r’ is following after the
match ‘r’ in search buffer. As ‘r’ is already encoded in the sequence the
modified length becomes 1 + 1 = 2 where additional length of 1 is for ‘r’
sequence in look ahead buffer.
Code = c(a)
For ‘c’ in look ahead buffer, there is no match found in search buffer.
Offset (o) = 0
Length (l) = 0
Code = c(c)
Offset (o) = 6
Length (l) = 2
Code = c(c)
Output IndexEntry
<0, c(w)>1 w
<0, c(a)> 2 a
<0, c(b)> 3 b
<3, c(a)> 4 ba
<3, c(r)> 5 br
<2, c(r)> 6 ar
<4, c(r)> 7 bar
<0, c(r)> 8 r
<2, c(c)> 9 ac
<3, c(c)> 10 bac
Sequence: w a b ba bra r bar r ac bac
This method assumes that a match is found around the window which is not
the case in practical applications.
The drawback of the L-78 algorithm is the memory size as the frequently
encountered symbols as well as the longer matches have to be stored as
entries in the dictionary.
If the dictionary is full then either the dictionary has to be restarted or some
of the entries have to be deleted.
/ Huffman Coding
Chap 4
E.g If the original size was k, then the size of the codebook would be .
Taking reasonable value k =16 and m=20. It gives a codebook size of .
This is obviously not a viable option.
For Shannon Fano coding procedure we do not need to build the entire
codebook instead, we simply obtain the code for the tag corresponding
to a given sequence. It is entirely feasible to code sequenced of length
20 or much more.
We can’t make large m Huffman Coding because we can’t got rates
closer to maximum entropy.
/ Huffman Coding
Chap 4
4. The key idea behind Huffman coding is to encode the most common
characters using shorter strings of bits than those used for less common
source characters.
6. We also need to know the external path length (sum of all paths from
root to external node) and internal path length (sum of all paths from
root to internal node).
Step 1: Create a leaf node for each character. Add the character and its
weight or frequency of occurrence to the priority queue.
Step 2: Repeat Steps 3 to 5 while the total number of nodes in the queue
is greater than 1
Step 3: Remove two nodes that have the lowest weight (or highest
priority)
8. Example
/ Huffman Coding
Chap 4
SymbolsCodeword
01
1
000
0010
0011
Verification
SymbolsCodeword
01
1
000
0010
0011
/ Huffman Coding
Chap 4
SymbolsCodeword
11
000
01
101
011
100
iii. Entropy:
Average length:
p () = 0. I5
p () = 0.25
p () = 0.10
Average length:
L = 2 bits/symbol
Entropy:
H = ()
= - 1/log2 [0.5 log (0.5) + 0.15 log (0.15) + 0.25 log (0.25) + 0.10 log
(0.10)]
H = 1.747 bits/symbol
/ AVL Tree
Chap 4
3. An AVL tree is a binary search tree which has the following properties:-
c. Each node in the AVL Tree possesses any one of the following
properties:
d. A node is called left heavy, if the largest path in its left sub tree is one
level larger than the largest path of its right sub tree.
e. A node is called right heavy, if the largest path in its right sub tree is
one level larger than the largest path of its left sub tree.
f. The node is called balanced, if the largest paths in both the right and
left sub trees are equal.
4. Consider the following example of AVL tree where every left subtree
has a height one greater than each right subtree.
7. Balance factor of a node = height othe left subtree - the height of the
right subtree
8. Each node of an AVL tree can have a balanced factor of -1, 0 or +1
only.
1. An AVL tree is a binary search tree which has the following properties:-
c. Each node in the AVL Tree possesses any one of the following
properties:
d. A node is called left heavy, if the largest path in its left sub tree is one
level larger than the largest path of its right sub tree.
e. A node is called right heavy, if the largest path in its right sub tree is
one level larger than the largest path of its left sub tree.
f. The node is called balanced, if the largest paths in both the right and
left sub trees are equal.
1. An AVL tree is a binary search tree which has the following properties:-
a. The sub-trees of every node differ in height by at most one.
c. Each node in the AVL Tree possesses any one of the following
properties:
d. A node is called left heavy, if the largest path in its left sub tree is one
level larger than the largest path of its right sub tree.
e. A node is called right heavy, if the largest path in its right sub tree is
one level larger than the largest path of its left sub tree.
f. The node is called balanced, if the largest paths in both the right and
left sub trees are equal.
Splay Tree
1. Splay tree is another varient of binary search tree. In a splay tree, the
recently accessed element is placed at the root of the tree.
2. A splay tree is defined a self - adjusted Binary Search Tree in which
every operation on an element rearrange the tree so that the element is
placed at the root position of the tree.
3. In a splay tree, every operation is performed at root of the tree. All the
operations on a splay tree are involved with a common operation called
"Splaying".
4. Splaying an element is the process of bringing it to the root position by
performing suitable rotation operations.
5. In a splay tree, splaying an element rearrange all the elements in the tree
so that splayed element is placed at root of the tree.
6. With the help of splaying an element we can bring most frequently used
element closer to the root of the tree so that any operation on those
element performed quickly.
7. In a splay tree, to splay any element we use the following rotation
operations...
1. Zig Rotation
2. Zag Rotation
3. Zig - Zig Rotation
4. Zag - Zag Rotation
5. Zig - Zag Rotation
6. Zag - Zig Rotation
Tries
I. Standard Tries:
The standard tries for a set of strings S is an ordered tree such that:
c. The paths from the external nodes to the root yield the strings of S.
/ Applications Of Trees
Chap 4
Graphs
Content
2. BFS
2.In the first stage, we visit all the vertices that are at the distance of one
edge away.
4.In the second stage, we visit all the new vertices we can reach at the
distance of two edges away from the source vertex “S”. These new
vertices, which are adjacent to level 1 vertices and not previously
assigned to a level, are placed into level 2, and so on.
5.The BFS traversal terminates when every vertex has been visited.
3. DFS
2.DFS can be started from any vertex and it continuous recursively until
all nodes are visited.
G= (V, E)
then,
V(G)={A,B,C,D,E,F}
E(G)={(AB),(AC),(BD),(BC),(DE),(DF),(EF)}
3. Linked Representation
1. Example of BFS
d. Now, we shall visit all the vertices adjacent to 1, then all the vertices
adjacent to 3 and then all the vertices adjacent to
/ Topological Sorting
Chap 5
2. Types of graphs:
a. The graphs should be directed: otherwise for any edge (u,v) there
would be a path from u to v and also from v to u, and hence they cannot
be ordered.
b. The graphs should be acyclic: otherwise for any two vertices u and v
on a cycle u would precede v and v would precede u.
Sorting Method
Indexed Sequential Search
Hashing
Binary Search
/ Sorting Method
Chap 6
#include<stdio.h>
#include<conio.h>
void insertion(int a[],int n)
{
int i,j,x,k;
for(i=1;i<=n-1;i++)
{ x=a[i];
for(j=i;a[j-1]>x && j>0;j=j-1)
{
a[j]=a[j-1];
}
a[j]=x;
printf("\n\n The array after pass no.%d: ",i);
for(k=0;k<=n-1;k++)
{
printf("%4d",a[k]);
}
}//end of outer for loop.
} //end of insertion function.
void main()
{
int a[1000],n,i;
printf("\n\nEnter an integer value for total no.s of
elements to be sorted: ");
scanf("%3d",&n);
for(i=0;i<=n-1;i++)
{
printf("\n\nEnter an integer value for element no.%d:
",i+1);
scanf("%4d",&a[i]);
}
insertion(a,n);
printf("\n\n\nFinally sorted array is : ");
for(i=0;i<=n-1;i++)
{
printf("%4d",a[i]);
}
}//end program.
2. Step by Step Example for Quick Sort a. Consider the unsorted values
{25, 13, 7, 34, 56, 23, 13, 96, 14, 2} with first element as pivot element
i.e 25 is pivot
b. Hence after quick sort the sorted array becomes 2, 07, 13, 13, 14, 23, 25,
34, 56, 96
/ Sorting Method
Chap 6
/ Sorting Method
Chap 6
Chap 6 / Hashing
8. What is hashing ? What is mean by collision?
Using modulo division method insert the following
values in a hash table of size 10. Show how many
collisions occurred. 99, 33, 23, 44, 56, 43, 19
Appeared in exams: Once
/ Hashing
Chap 6
Thus, it becomes a data structure in which insertion and search operations are
very fast irrespective of the size of the data. Hash Table uses an array as a
storage medium and uses hash technique to generate an index where an
element is to be inserted or is to be located from.
Hash function
A hash function is any function that can be used to map a data set of an
arbitrary size to a data set of a fixed size, which falls into the hash table. The
values returned by a hash function are called hash values, hash codes, hash
sums, or simply hashes.
The division method is quite good for just about any value of M and
since it requires only a single division operation, the method works very
fast. However, extra care should be taken to select a suitable value for
M.
Multiplication Method:
Step 4: Multiply the result of Step 3 by the size of hash table (m).
where (kA mod 1) gives the fractional part of kA and m is the total
number of indices in the hash table.
Mid-Square Method:
Step 1: Square the value of the key. That is, find k2.
The algorithm works well because most or all digits of the key value
contribute to the result. This is because all the digits in the original key
value contribute to produce the middle digits of the squared value.
Folding Method: The folding method works in the following two steps:
Step 1: Divide the key value into a number of parts. That is, divide k
into parts k1, k2, ..., kn, where each part has the same number of digits
except the last part which may have lesser digits than the other parts.
Step 2: Add the individual parts. That is, obtain the sum of k1 + k2 + ...
+ kn. The hash value is produced by ignoring the last carry, if any.
Note that the number of digits in each part of the key will vary depending
upon the size of the hash table. For example, if the hash table has a size of
1000, then there are 1000 locations in the hash table.
To address these 1000 locations, we need at least three digits; therefore, each
part of the key must have three digits except the last part which may have
lesser digits.
Chap 6 / Hashing
10. Using Linear probing and Quadratic probing,
insert the following values in the hash table of size
10.Show how many collisions occur in each
iterations 28, 55, 71, 67, 11, 10, 90, 44
Appeared in exams: 2 times
1. Linear Probing
1. Quadratic Probing
Chap 6/ Hashing
11. Hash the following in a table of size 11. Use any
two collision resolution techniques: 23, 55, 10, 71,
67, 32, 100, 18, 10, 90, 44.
Appeared in exams: Once
1. Linear Probing
1. Quadratic Probing
/ Binary Search
Chap 6
Cms = Cmv
Now, consider that the probability for searching a requested data item is
1/n, then,
It can be easily observed that for successful and unsuccessful search the
expected number of cases is given by:
On the basis of the above analysis the time complexity of Binary Search
is:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
int n,i,search,f=0,low,high,mid,a[100];
clrscr();
printf("Enter the size of array");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter a[%d] ",i);
scanf("%d",&a[i]);
}
printf("Enter the search element:");
scanf("%d",&search);
low=0;
high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(search<a[mid])
{
high=mid-1;
}
else if(search>a[mid])
{
low=mid+1;
}
else
{
f=1;
printf("Element found at %d:",mid);
exit(1);
}
}
if(f==0)
{
printf("not present");
}
getch();
}
Congratulations! you've done it.
Hope you found this book useful. We'd love to hear your comments. Just
send them over to helpdesk@ques10.com .
Answer:
— Found repeated in "+ paper_year + " • "+ lesson_no +" • "+ seq_num
+"