Professional Documents
Culture Documents
Data Structures
Data Structures
struct structure_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object _names;
where structure_name is a name for the structure type, object_name can be a set of valid
identifiers for objects that have the type of this structure. Within braces { } there is a list
with the data members, each one is specified with a type and a valid identifier as its
name.
The first thing we have to know is that a data structure creates a new type: Once a data
structure is declared, a new type with the identifier specified as structure_name is created
and can be used in the rest of the program as if it was any other type.
3. Evaluate the following prefix expression " ++ 26 + - 1324" (Similar types can be asked)
Prefix expression evaluation : ++26+-1324
++26+-1324
+(2+6)+(1-3)24
+(2+6)((1-3)+(24))
(2+6)+((1-3)+(24))
8+(-2+24)
30
Stack can be described as a pointer as it contains a head pointer always pointing to the
topmost element of the stack. The Push and Pop operations are performed using this
pointer.
#include<conio.h>
#include<iostream.h>
#include<process.h>
void main()
{
int a[10],i,s=0,n,loc,flag=0;
clrscr();
cout<<"\n Enter the no. of element to store:\n";
cin>>n;
cout<<"Enter the Elements:\n";
for(i=0;i<n;i++)
cin>>a[i];
if(binarysearch(a,n,s,&loc))
cout<<"\nThe element "<<s<< " is available at location"<<loc<<endl;
else
cout<<"\nThe element "<<s<< " is not found in the List"<<endl;
}
8. Write programs for Bubble Sort, Quick sort
Program for bubble sort, Quick sort :
#include<stdio.h>
#include<conio.h>
#define SIZE 5
void main()
{
int a[SIZE],n,i,j,temp;
clrscr();
printf("enter the elements ");
for(i=0;i<SIZE;i++)
scanf("%d",&a[i]);
printf("the sorted list is :->\n");
for(i=0;i<SIZE;i++)
for(j=i;j<SIZE-i;j++)
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
for(i=0;i<SIZE;i++)
printf("%d",a[i]);
getch();
}
/*QUICK SORT*/
#include<stdio.h>
#include<conio.h>
void main()
{
int arr[20],n,i;
clrscr();
printf("\nQUICk SORT\n");
printf("Enter the no.of elements:");
scanf("%d",&n);
printf("Enter the elements:");
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
printf("\nArray before sorting:\n");
for(i=0;i<n;i++)
printf("%d\t",arr[i]);
quicksort(arr,0,n);
printf("\nArray after sorting:\n");
for(i=0;i<n;i++)
printf("%d\t",arr[i]);
getch();
}
Singly linked list: It has only head part and corresponding references to the next nodes.
Doubly linked list: A linked list which both head and tail parts, thus allowing the
traversal in bi-directional fashion. Except the first node, the head node refers to the
previous node.
Circular linked list: A linked list whose last node has reference to the first node.
public :
LinkList()
{
Node *t1 = new Node();
t1->prev = NULL;
t1->value = 4;
t1->next = NULL;
first = t1;
~LinkList()
{
Node *temp = first, *current = first;
while(current != NULL)
{
temp = current->next;
delete current;
current = temp;
}
void Display()
{
Node *temp;
for(temp = first; temp != NULL; temp = temp->next)
{
cout<<temp->value<<" , ";
}
cout<<endl;
}
void Sort()
{
Node *current, *cur;
// Initialize them
current_next = current->next;
min_previous = minimum->prev;
min_next = minimum->next;
current_previous = current->prev;
if(current_previous == NULL)
{
// Change the First Node
first = minimum;
}
if(current->next == minimum)
{
// Nodes are Adjacent
minimum->prev = current_previous;
minimum->next = current;
current->prev = minimum;
current->next = min_next;
if(min_next)
{
min_next->prev = current;
}
if(current_previous)
{
current_previous->next = minimum;
}
}
else
{
minimum->prev = current_previous;
minimum->next = current_next;
current->prev = min_previous;
current->next = min_next;
if(current_next)
{
current_next->prev = minimum;
}
if(min_previous)
{
min_previous->next = current;
}
if(min_next)
{
min_next->prev = current;
}
if(current_previous)
{
current_previous->next = minimum;
}
}
current = minimum;
}
}
}
};
void main()
{
LinkList list;
cout<<"LinkList = ";
list.Display();
cout<<"\n\nSorting \n\n";
list.Sort();
cout<<"LinkList = ";
list.Display();
}
11. Write the programs for Linked List (Insertion and Deletion) operations
Programs for Linked List operations :
#include<iostream>
#include<stdlib.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define NULL 0
class AVL;
class AVLNODE
{
friend class AVL;
private:
int data;
AVLNODE *left,*right;
int bf;
};
class AVL
{
private:
AVLNODE *root;
public:
AVLNODE *loc,*par;
AVL()
{
root=NULL;
}
int insert(int);
void displayitem();
void display(AVLNODE *);
void removeitem(int);
void remove1(AVLNODE *,AVLNODE *,int);
void remove2(AVLNODE *,AVLNODE *,int);
void search(int x);
void search1(AVLNODE *,int);
};
int AVL::insert(int x)
{
AVLNODE *a,*b,*c,*f,*p,*q,*y,*clchild,*crchild;
int found,unbalanced;
int d;
if(!root) //special case empty tree
{ y=new AVLNODE;
y->data=x;
root=y;
root->bf=0;
root->left=root->right=NULL;
return TRUE; }
//phase 1:locate insertion point for x.a keeps track of the most
// recent node with balance factor +/-1,and f is the parent of a
// q follows p through the tree.
f=NULL;
a=p=root;
q=NULL;
found=FALSE;
while(p&&!found)
{ //search for insertion point for x
if(p->bf)
{
a=p;
f=q;
}
if(x<p->data) //take left branch
{
q=p;
p=p->left;
}
else if(x>p->data)
{
q=p;
p=p->right;
}
else
{
y=p;
found=TRUE;
}
} //end while
//phase 2:insert and rebalance.x is not in the tree and
// may be inserted as the appropriate child of q.
if(!found)
{
y = new AVLNODE;
y->data=x;
y->left=y->right=NULL;
y->bf=0;
if(x<q->data) //insert as left child
q->left=y;
else
q->right=y; //insert as right child
//adjust balance factors of nodes on path from a to q
//note that by the definition of a,all nodes on this
//path must have balance factors of 0 and so will change
//to +/- d=+1 implies that x is inserted in the left
// subtree of a d=-1 implies
//to that x inserted in the right subtree of a.
if(x>a->data)
{
p=a->right;
b=p;
d=-1;
}
else
{
p=a->left;
b=p;
d=1;
}
while(p!=y)
if(x>p->data) //height of right increases by 1
{
p->bf=-1;
p=p->right;
}
else //height of left increases by 1
{
p->bf=1;
p=p->left;
}
//is tree unbalanced
unbalanced=TRUE;
if(!(a->bf)||!(a->bf+d))
{ //tree still balanced
a->bf+=d;
unbalanced=FALSE;
}
if(unbalanced) //tree unbalanced,determine rotation type
{
if(d==1)
{ //left imbalance
if(b->bf==1) //rotation type LL
{
a->left=b->right;
b->right=a;
a->bf=0;
b->bf=0;
}
else //rotation type LR
{
c=b->right;
b->right=c->left;
a->left=c->right;
c->left=b;
c->right=a;
switch(c->bf)
{
case 1: a->bf=-1; //LR(b)
b->bf=0;
break;
case -1:b->bf=1; //LR(c)
a->bf=0;
break;
case 0: b->bf=0; //LR(a)
a->bf=0;
break;
}
c->bf=0;
b=c; //b is the new root
} //end of LR
} //end of left imbalance
else //right imbalance
{
if(b->bf==-1) //rotation type RR
{
a->right=b->left;
b->left=a;
a->bf=0;
b->bf=0;
}
else //rotation type LR
{
c=b->right;
b->right=c->left;
a->right=c->left;
c->right=b;
c->left=a;
switch(c->bf)
{
case 1: a->bf=-1; //LR(b)
b->bf=0;
break;
case -1:b->bf=1; //LR(c)
a->bf=0;
break;
case 0: b->bf=0; //LR(a)
a->bf=0;
break;
}
c->bf=0;
b=c; //b is the new root
} //end of LR
}
//subtree with root b has been rebalanced and is the new subtree
if(!f)
root=b;
else if(a==f->left)
f->left=b;
else if(a==f->right)
f->right=b;
} //end of if unbalanced
return TRUE;
} //end of if(!found)
return FALSE;
} //end of AVL INSERTION
void AVL::displayitem()
{
display(root);
}
void AVL::display(AVLNODE *temp)
{
if(temp==NULL)
return;
cout<<temp->data<<" ";
display(temp->left);
display(temp->right);
}
void AVL::removeitem(int x)
{
search(x);
if(loc==NULL)
{
cout<<"\nitem is not in tree";
return;
}
if(loc->right!=NULL&&loc->left!=NULL)
remove1(loc,par,x);
else
remove2(loc,par,x);
}
void AVL::remove1(AVLNODE *l,AVLNODE *p,int x)
{
AVLNODE *ptr,*save,*suc,*psuc;
ptr=l->right;
save=l;
while(ptr->left!=NULL)
{
save=ptr;
ptr=ptr->left;
}
suc=ptr;
psuc=save;
remove2(suc,psuc,x);
if(p!=NULL)
if(l==p->left)
p->left=suc;
else
p->right=suc;
else
root=l;
suc->left=l->left;
suc->right=l->right;
return;
}
void AVL::remove2(AVLNODE *s,AVLNODE *p,int x)
{
AVLNODE *child;
if(s->left==NULL && s->right==NULL)
child=NULL;
else if(s->left!=NULL)
child=s->left;
else
child=s->right;
if(p!=NULL)
if(s==p->left)
p->left=child;
else
p->right=child;
else
root=child;
}
void AVL::search(int x)
{
search1(root,x);
}
void AVL::search1(AVLNODE *temp,int x)
{
AVLNODE *ptr,*save;
int flag;
if(temp==NULL)
{
cout<<"\nthe tree is empty";
return;
}
if(temp->data==x)
{
cout<<"\nthe item is root and is found";
par=NULL;
loc=temp;
par->left=NULL;
par->right=NULL;
return; }
if( x < temp->data)
{
ptr=temp->left;
save=temp;
}
else
{
ptr=temp->right;
save=temp;
}
while(ptr!=NULL)
{
if(x==ptr->data)
{ flag=1;
cout<<"\nitemfound";
loc=ptr;
par=save;
}
if(x<ptr->data)
ptr=ptr->left;
else
ptr=ptr->right;
}
if(flag!=1)
{
cout<<"item is not there in tree";
loc=NULL;
par=NULL;
cout<<loc;
cout<<par;
}
}
main()
{
AVL a;
int x,y,c;
char ch;
do
{
cout<<"\n1.insert";
cout<<"\n2.display";
cout<<"\n3.delete";
cout<<"\n4.search";
cout<<"\n5.exit";
cout<<"\nEnter u r choice to perform on AVL tree";
cin>>c;
switch(c)
{
case 1:cout<<"\nEnter an element to insert into tree";
cin>>x;
a.insert(x);
break;
case 2:a.displayitem(); break;
case 3:cout<<"\nEnter an item to deletion";
cin>>y;
a.removeitem(y);
break;
case 4:cout<<"\nEnter an element to search";
cin>>c;
a.search(c);
break;
case 5:exit(0); break;
default :cout<<"\nInvalid option try again";
}
cout<<"\ndo u want to continue";
cin>>ch;
}
while(ch=='y'||ch=='Y');
}
12. What data structure would you mostly likely see in a non recursive implementation of
a recursive algorithm?
data structure would you most likely see in a non recursive implementation of a
recursive algorithm :
Stack
13. What do you mean by Base case, Recursive case, Binding Time, Run-Time Stack and
Tail Recursion?
These terms are found in Recursion.
Base Case: it is the case in recursion where the answer is known, or we can say the
termination condition for a recursion to unwind back.
For example to find Factorial of num using recursion:
int Fact(int num){
if(num==1 || num==0)//base case return 1; else // recursive case: return num*Fact(num-
1); }.
Recursive case: It is the case which brings us to the closer answer.
Run Time Stack: It is a system stack us to save the frame stack of a function every
recursion or every call. This frame stack consists of the return address, local variables and
return value if any.
Tail Recursion: The case where the function consist of single recursive call and it is the
last statement to be executed. A tail Recursion can be replace by iteration. The above
function consists of tail recursion case. whereas the below function does not.
void binary(int start,int end,int el){ int mid; if(end>start){ mid=(start+end)/2;
if(el==ar[mid]) return mid; else{ if(el>ar[mid]) binary(mid+1,end,ele); else
binary(start,mid-11,ele); } } }
14. Explain quick sort and merge sort algorithms and derive the time-constraint
relation for these.
Quick sort algorithm
function quicksort(array)
var list less, greater
if length(array) ≤ 1
return array
select and remove a pivot value pivot from array
for each x in array
if x ≤ pivot then append x to less
else append x to greater
return concatenate(quicksort(less), pivot, quicksort(greater))
Merge sort
function mergesort(m)
var list left, right, result
if length(m) ≤ 1
return m
else
var middle = length(m) / 2
for each x in m up to middle - 1
add x to left
for each x in m at and after middle
add x to right
left = mergesort(left)
right = mergesort(right)
if last(left) ≤ first(right)
append right to left
return left
result = merge(left, right)
return result
function merge(left,right)
var list result
while length(left) > 0 and length(right) > 0
if first(left) ≤ first(right)
append first(left) to result
left = rest(left)
else
append first(right) to result
right = rest(right)
if length(left) > 0
append rest(left) to result
if length(right) > 0
append rest(right) to result
return result
Suppose (for simplicity) that n = 2k for some entire k. Let T(n) the time used to sort n elements.
As we can perform separation and merging in linear time, it takes cn time to perform these two
steps, for some constant c. So,
O(n2)
Binary Search:
o Binary search is the process of locating an element in a sorted list. The search
starts by dividing the list into two parts.
The algorithm compares the median value. If the search element is less than the median
value, the top list only will be searched, after finding the middle element of that list.
The process continues until the element is found or the search in the top list is completed.
The same process is continued for the bottom list, until the element is found or the search
in the bottom list is completed. If an element is found that must be the median value.
Fibonacci Search:
Fibonacci search is a process of searching a sorted array by utilizing divide and conquer
algorithm.
Fibonacci search examines locations whose addresses have lower dispersion.
When the search element has non-uniform access memory storage, the Fibonacci search
algorithm reduces the average time needed for accessing a storage location.
16. What is the maximum total number of nodes in a tree that has N levels? Note that the
root is level (zero)
If root is at level 0 then :
Case 0:
When level is 1 max nodes is 1
Case 1:
When level is 1 then max would be 3.
Case 2:
When level is 2 then max nodes would be 7
2^(0+1)-1=1
2^(1+1)-1=3
2^(2+1)-1=7
17. How many different binary trees and binary search trees can be made from three
nodes that contain the key values 1, 2 & 3?
18. A list is ordered from smaller to largest when a sort is called. Which sort would take the
longest time to execute?
A list is ordered from smaller to largest when a sort is called Which sort would take the longest
time to execute -- Quick Sort
19. A list is ordered from smaller to largest when a sort is called. Which sort would take the
shortest time to execute?
A list is ordered from smaller to largest when a sort is called Which sort would take the shortest
time to execute –Insertion Sort
20. When will you sort an array of pointers to list elements, rather than sorting the
elements themselves?
If the Data structures that we are sorting are big and located at different places then we prefer
sorting pointers rather than data itself .
21. The element being searched for is not found in an array of 100 elements. What is the
average number of comparisons needed in a sequential search to determine that the element
is not there, if the elements are completely unordered?
Avarage number of comparision will be (N+1)/2(N-size of array).Because:If elements is in 1st
position no of cpmparision will be one and if the element is in the last position then no of
comparisions will be N.
22. What is the average number of comparisons needed in a sequential search to determine
the position of an element in an array of 100 elements, if the elements are ordered from
largest to smallest?
Avarage number of comparision will be (N+1)/2(N-size of array).Because:If elements is in 1st
position no of cpmparision will be one and if the element is in the last position then
no of comparisions will be N.
25. Which data structure is needed to convert infix notations to post fix notations?
Stack is data structure needed to convert infix notation to postfix notation.
Syntax errors -- Errors in spelling and grammar.You can use the compiler or interpreter to
uncover syntax errors.You must have a good working knowledge of error messages to discover
the cause of the error.
Logical errors -- Errors that indicate the logic used when coding the program failed to solve the
problem.You do not get error messages with logic errors.Your only clue to the existence of logic
errors is the production of wrong solutions.
Runtime Error occurs at run-time.Such error cause a program to end abrubtly or even cause
system shut-down.Such errors are hard to detect.
e.g. Error caused due to low system memory.
27. In which data structure, elements can be added or removed at either end, but not in the
middle?
A double ended queue (deque) is a linear list in which elements can be added or removed at
either end but not in the middle..it is the contraction of name double ended queue..
28. How will inorder, preorder and postorder traversals print the elements of a tree?
Preorder ,postorder ,inorder traversals
}
void postorder(node * root)
{
if(root!= NULL)
{
postorder(root->leftchild);
postorder(root->rightchild);
printf("%d ",root->data);
}
else
return;
}
}
in order:LOR
pre order:OLR
post order:LRO
L=LEFT CHILD
R=RIGHT CHILD
O=ROOT NODE
Parenthesis are used to define the sequence or priority of execution of operations which is useful
in infix notation. Whereas we have already taken the consideration of order of execution of
operands during the time of conversion to prefix or postfix form.These orders are maintained
with the help of Stack
i.e. Last in First out. So we donot need parenthesis in
prefix and postfix notions.
30. Which one is faster? A binary search of an ordered set of elements in an array or a
sequential search of the elements.
Faster :- Binary search vs Sequential search
The binary search is faster than the sequential search.Thecomplexity of binary search is 'log n'
where as thecomplexity of sequential search is 'n'.Since each time weare proceeding we have to
deal with only half of the elements of the array than the previous one.So we can easily get a
number from an array of elements through binary search than sequential search.