Data Structures Concepts and Programming Questions
Data Structures Concepts and Programming Questions
What are the various operations that can be performed on different Data
Structures?
● Insertion ? Add a new data item in the given collection of data items.
● Deletion ? Delete an existing data item from the given collection of data items.
● Traversal ? Access each data item exactly once so that it can be processed.
● Searching ? Find out the location of the data item if it exists in the given collection
of data items.
M Muzammal Murtaza - BITF16A525
● Sorting ? Arranging the data items in some order i.e. in ascending or descending
order in case of numerical data and in dictionary order in case of alphanumeric
data.
A linked list is a linear data structure, in which the elements are not stored at contiguous
memory locations. The elements in a linked list are linked using pointers. In simple words, a
linked list consists of nodes where each node contains a data field and a reference(link) to the
next node in the list.
● The size of the arrays is fixed, Linked Lists are Dynamic in size.
● Inserting and deleting a new element in an array of elements is expensive, Whereas
both insertion and deletion can easily be done in Linked Lists.
● Random access is not allowed in Linked Listed.
● Extra memory space for a pointer is required with each element of the Linked list.
● Arrays have better cache locality that can make a pretty big difference in
performance.
https://www.geeksforgeeks.org/linked-list-vs-array/
Applications of Stack:
https://www.geeksforgeeks.org/implement-a-stack-using-singly-linked-list/
elements. Mainly the following are basic operations on queue: Enqueue, Dequeue, Front, Rear
The difference between stacks and queues is in removing. In a stack we remove the item the
most recently added; in a queue, we remove the item the least recently added. Both Queues and
https://www.geeksforgeeks.org/queue-linked-list-implementation/
● Infix notation: X
+ Y – Operators are written in-between their operands. This is the
usual way we write expressions. An expression such as
A * ( B + C ) / D
● Postfix notation (also known as “Reverse Polish notation”): X
Y + O
perators are
written after their operands. The infix expression given above is equivalent to
A B C + * D/
M Muzammal Murtaza - BITF16A525
A linked list is a linear data structure (like arrays) where each element is a separate object. Each
element (that is node) of a list is comprising of two items – the data and a reference to the next
1. Singly Linked List : In this type of linked list, every node stores address or reference
of next node in list and the last node has next address or reference as NULL. For
example 1->2->3->4->NULL
2. Doubly Linked List : H
ere, here are two references associated with each node, One
of the reference points to the next node and one to the previous node. Eg.
NULL<-1<->2<->3->NULL
3. Circular Linked List : C
ircular linked list is a linked list where all nodes are
connected to form a circle. There is no NULL at the end. A circular linked list can be
a singly circular linked list or doubly circular linked list. Eg. 1->2->3->1 [The next
pointer of last node is pointing to the first]
M Muzammal Murtaza - BITF16A525
a graph. It uses a Queue data structure which follows first in first out. In BFS, one vertex is
selected at a time when it is visited and marked then its adjacent are visited and stored in the
Ex-
A
/\
B C
/ /\
D E F
Output is:
A, B, C, D, E, F
performs two stages, first visited vertices are pushed into stack and second if there are no
Ex-
A
/\
B C
/ /\
D E F
M Muzammal Murtaza - BITF16A525
Output is:
A, B, D, C, E, F
S.NO
BFS DFS
. BFS stands for Breadth First Search. DFS stands for Depth First Search.
2
BFS(Breadth First Search) uses Queue
. DFS(Depth First Search) uses Stack data
data structure for finding the shortest
structure.
path.
3
BFS is more suitable for searching
. DFS is more suitable when there are
vertices which are closer to the given
solutions away from source.
source.
M Muzammal Murtaza - BITF16A525
5
The Time complexity of BFS is O(V + E), The Time complexity of DFS is also O(V
. where V stands for vertices and E stands + E), where V stands for vertices and E
for edges. stands for edges.
Which data structures are used for BFS and DFS of a graph?
Binary Tree
Binary Tree: A tree whose elements have at most 2 children is called a binary tree. Since each
element in a binary tree can have only 2 children, we typically name them the left and right child.
Binary Tree Representation in C++: A tree is represented by a pointer to the topmost node in a
tree. If the tree is empty, then the value of the root is NULL.
1. Data
Class node
int data;
node *left;
node *right;
};
M Muzammal Murtaza - BITF16A525
properties:
● The left subtree of a node contains only nodes with keys lesser than the node’s key.
● The right subtree of a node contains only nodes with keys greater than the node’s
key.
● The left and right subtree each must also be a binary search tree.
There must be no duplicate nodes.
Array Θ(1) Θ(n) Θ(n) Θ(n) O(1) O(n) O(n) O(n) O(n)
M Muzammal Murtaza - BITF16A525
Stack Θ(n) Θ(n) Θ(1) Θ(1) O(n) O(n) O(1) O(1) O(n)
Queue Θ(n) Θ(n) Θ(1) Θ(1) O(n) O(n) O(1) O(1) O(n)
Singly-Linked Θ(n) Θ(n) Θ(1) Θ(1) O(n) O(n) O(1) O(1) O(n)
List
Doubly-Linked Θ(n) Θ(n) Θ(1) Θ(1) O(n) O(n) O(1) O(1) O(n)
List
Skip List Θ(log( Θ(log( Θ(log(n Θ(lo O(n) O(n) O(n) O(n) O(n
n)) n)) )) g(n)) log(n))
Hash Table N/A Θ(1) Θ(1) Θ(1) N/A O(n) O(n) O(n) O(n)
Binary Search Θ(log( Θ(log( Θ(log(n Θ(lo O(n) O(n) O(n) O(n) O(n)
Tree n)) n)) )) g(n))
Cartesian N/A Θ(log( Θ(log(n Θ(lo N/A O(n) O(n) O(n) O(n)
Tree n)) )) g(n))
B-Tree Θ(log( Θ(log( Θ(log(n Θ(lo O(log( O(log( O(log( O(log O(n)
n)) n)) )) g(n)) n)) n)) n)) (n))
Red-Black Θ(log( Θ(log( Θ(log(n Θ(lo O(log( O(log( O(log( O(log O(n)
Tree n)) n)) )) g(n)) n)) n)) n)) (n))
Splay Tree N/A Θ(log( Θ(log(n Θ(lo N/A O(log( O(log( O(log O(n)
n)) )) g(n)) n)) n)) (n))
M Muzammal Murtaza - BITF16A525
AVL Tree Θ(log( Θ(log( Θ(log(n Θ(lo O(log( O(log( O(log( O(log O(n)
n)) n)) )) g(n)) n)) n)) n)) (n))
KD Tree Θ(log( Θ(log( Θ(log(n Θ(lo O(n) O(n) O(n) O(n) O(n)
n)) n)) )) g(n))
}
else{
temp->next=head;
head=temp;
}
}
}
else{
Node *tmp=head;
while(tmp->next!=NULL){
tmp=tmp->next;
}
M Muzammal Murtaza - BITF16A525
tmp->next=temp;
}
Delete N nodes after M nodes in a linked list till the end of list
int count;
while (curr)
// Skip M nodes
curr = curr->next;
if (curr == NULL)
return;
t = curr->next;
Node *temp = t;
t = t->next;
free(temp);
curr->next = t;
curr = t;
}
}
M Muzammal Murtaza - BITF16A525
if(slow == fast) {
removeLoop(slow_p, list);
}
}
cout<<"\nno loop detected\n";
return;
}
/* Function to remove loop.
loop_node --> Pointer to one of the loop nodes
head --> Pointer to the start node of the linked list */
void removeLoop(struct Node* loop_node, struct Node* head)
{
struct Node* ptr1;
struct Node* ptr2;
/* If ptr2 did't reach ptr1 then try the next node after ptr1 */
ptr1 = ptr1->next;
}
/* After the end of loop ptr2 is the last node of the loop. So
make next of ptr2 as NULL */
ptr2->next = NULL;
M Muzammal Murtaza - BITF16A525
temp = head;
return;
}
Recursive approach
void printNthFromLast(struct Node* head, int n)
{
static int i = 0;
if (head == NULL)
return;
printNthFromLast(head->next, n);
M Muzammal Murtaza - BITF16A525
if (++i == n)
printf("%d", head->data);
}
Find the nth element in a linked list from the end using two pointers
Maintain two pointers – reference pointer and main pointer. Initialize both reference and main
pointers to head. First, move the reference pointer to n nodes from head. Now move both
pointers one by one until the reference pointer reaches the end. Now the main pointer will point
to nth node from the end. Return the main pointer.
int count = 0;
if(head != NULL)
{
while( count < n )
{
if(ref_ptr == NULL)
{
printf("%d is greater than the no. of "
"nodes in list", n);
return;
}
ref_ptr = ref_ptr->next;
count++;
} /* End of while*/
while(ref_ptr != NULL)
{
main_ptr = main_ptr->next;
ref_ptr = ref_ptr->next;
}
printf("Node no. %d from last is %d ",
n, main_ptr->data);
}
}
M Muzammal Murtaza - BITF16A525
return count;
}
// If first is greater
if (c1 > c2) {
d = c1 - c2;
return _getIntesectionNode(d, head1, head2);
}
else {
d = c2 - c1;
return _getIntesectionNode(d, head2, head1);
}
}
M Muzammal Murtaza - BITF16A525
return -1;
}
prev=curr;
curr=next;
}
head=prev;
}
while(currNode != NULL){
int val = currNode -> data;
else{
evenEnd -> next = currNode;
evenEnd = evenEnd -> next;
}
}
temp = temp->next;
M Muzammal Murtaza - BITF16A525
if (second == INT_MIN)
cout << "There is no second largest element\n";
else
cout << "The second largest element is " << second;
/* fast_ptr would become NULL when there are even elements in list.
And not NULL for odd elements. We need to skip the middle node
for odd case and store it somewhere so that we can restore the
original list*/
if (fast_ptr != NULL) {
midnode = slow_ptr;
slow_ptr = slow_ptr->next;
}
// Now reverse the second half and compare it with first half
second_half = slow_ptr;
prev_of_slow_ptr->next = NULL; // NULL terminate first half
reverse(&second_half); // Reverse the second half
res = compareLists(head, second_half); // compare
// Insert data.
if(value > root->data)
{
// Insert right node data, if the 'value'
// to be inserted is greater than 'root' node data.
// Recursive function to check if two given binary trees are identical or not
int isIdentical(Node* x, Node* y)
{
// if both trees are empty, return true
if (x == nullptr && y == nullptr)
return 1;
// if both trees are non-empty and value of their root node matches,
// recur for their left and right sub-tree
return (x && y) && (x->key == y->key) &&
isIdentical(x->left, y->left) &&
isIdentical(x->right, y->right);
}
}
return(current->data);
}
else
return getLeafCount(node->left)+
getLeafCount(node->right);
}