Question Bank

advertisement

Algorithm, Arrays

Ques 1:Define an algorithm. What are the properties of an algorithm? What are the types of algorithms?

Ans: Algorithm: A step by step process to get the solution for a well defined problem.

Properties of an algorithm:

- Should be written in simple English

- Should be unambiguous, precise and lucid

- Should provide the correct solutions

- Should have an end point

- The output statements should follow inpu t, process instructions

- The initial statements should be of input statements

- Should have finite number of steps

- Every statement should be definitive

Types of algorithms:

-- Simple recursive algorithms. Ex: Searching an element in a list

– Backtracking algorithms Ex: Depth-first recursive search in a tree

– Divide and conquer algorithms. Ex: Quick sort and merge sort

– Dynamic programming algorithms. Ex: Generation of Fibonacci series

– Greedy algorithms Ex: Counting currency

– Branch and bound algorithms. Ex: Travelling salesman (visiting each city once and minimize the total distance travelled)

– Brute force algorithms. Ex: Finding the best path for a travelling salesman

– Randomized algorithms. Ex. Using a random number to choose a pivot in quick sort).

Ques 2:Define in brief an array. What are the types of array operations?

Ans: An array is a set of homogeneous elements. Every element is referred by an index.

Arrays are used for storing the data until the application expires in the main memory of the computer system. So that, the elements can be accessed at any time. The operations are:

- Adding elements

- Sorting elements

- Searching elements

- Re-arranging the elements

- Performing matrix operations

- Pre-fix and post-fix operations

Ques 3:Define a linear and non linear data structure.

Ans: Linear data structure: A linear data structure traverses the data elements sequentially, in which only one data element can directly be reached. Ex: Arrays, Linked Lists.

Non-Linear data structure: Every data item is attached to several other data items in a way that is specific for reflecting relationships. The data items are not arranged in a sequential structure. Ex:

Trees, Graphs

Ques 5: What is a data structure? What are the types of data structures?

Ans: The scheme of organizing related information is known as ‘data structure’. The types of data structure are:

Lists: A group of similar items with connectivity to the previous or/and next data items.

Arrays: A set of homogeneous values

Records: A set of fields, where each field consists of data belongs to one data type.

Trees: A data structure where the data is organized in a hierarchical structure. This type of data structure follows the sorted order of insertion, deletion and modification of data items.

Tables: Data is persisted in the form of rows and columns. These are similar to records, where the result or manipulation of data is reflected for the whole table.

Ques 6: What is an iterative algorithm?

Ans: The process of attempting for solving a problem which finds successive approximations for solution, starting from an initial guess. The result of repeated calculations is a sequence of approximate values for the quantities of interest.

Ques 7:What is an recursive algorithm?

Recursive algorithm is a method of simplification that divides the problem into sub-problems of the same nature. The result of one recursion is the input for the next recursion. The repletion is in the self-similar fashion. The algorithm calls itself with smaller input values and obtains the results by simply performing the operations on these smaller values. Generation of factorial, Fibonacci number series are the examples of recursive algorithms.

Ques 8:What is the Huffman algorithm?

Ans:In Huffman Algorithm, a set of nodes assigned with values if fed to the algorithm.

Initially 2 nodes are considered and their sum forms their parent node. When a new element is considered, it can be added to the tree. Its value and the previously calculated sum of the tree are used to form the new node which in turn becomes their parent.

Ques 9: List out the areas in which data structures are applied extensively?

·

·

·

·

·

Ans: The name of areas are:

·

Compiler Design,

Operating System,

Database Management System,

Statistical analysis package,

Numerical Analysis,

Graphics,

·

·

Artificial Intelligence,

Simulation

Ques 10:What are the major data structures used in the following areas : RDBMS, Network data model & Hierarchical data model.

Ans: The major data structures used are as follows:

·

·

·

RDBMS - Array (i.e. Array of structures)

Network data model - Graph

Hierarchical data model - Trees

12.

Ques 11:What is the difference between NULL AND VOID pointer?

Ans: NULL can be value for pointer type variables.

VOID is a type identifier which has not size.

NULL and void are not same. Example: void* ptr = NULL;

Ques 12How memory is reserved using a declaration statement ?

Ans: Memory is reserved using data type in the variable declaration. A programming language implementation has predefined sizes for its data types.

For example, in C# the declaration int i; will reserve 32 bits for variable i.

A pointer declaration reserves memory for the address or the pointer variable, but not for the data that it will point to. The memory for the data pointed by a pointer has to be allocated at runtime.

The memory reserved by the compiler for simple variables and for storing pointer address is allocated on the stack, while the memory allocated for pointer referenced data at runtime is allocated on the heap.

Ques 13:What are Arrays?

Ans: An array is a series of elements. These elements are of the same type. Each element can be individually accessed using an index. For e.g an array of integers. Array elements are stored one after another (contiguous) in the memory. An array can have more than one dimension. First element in an array starts with 0.

Ques 14: Explain two-dimensional array.

Ans: An array with two dimensions is called as a two-dimensional array. It is also called as a matrix.

In C, a two dimensional array is initialized as int arr[nb_of_rows] [nb_of_columns]. Hence, two dimensional arrays can be considered as a grid. An element in a two dimensional can be accessed by mentioning its row and column. If the array has 20 integer values, it will occupy 80 bytes in memory

(assuming 4 bytes for an integer). All of the bytes are in consecutive memory locations, the first row occupying the first 20 bytes, the second the next 20, and so on.

Ques 15: Write a Program implementing deletion operation in an array.

Ans:

#include<stdio.h>

#include<conio.h> int i,n; main()

{ int a[100],pos; void delete(int a[],int,int); clrscr(); printf("How many elements in the array\n"); scanf("%d",&n); printf("Enter the element of the array\n"); for(i=0;i<=n-1;i++) scanf("%d",&a[i]); printf("On which postion element do you want delete\n"); scanf("%d",&pos); delete(a,pos,n); getch();

} void delete(int a[],int pos,int n)

{ int j,item; item=a[pos]; for(j=pos;j<=n-1;j++)

{ a[j]=a[j+1];

} n=n-1; for(i=0;i<=n-1;i++) printf("%d\n",a[i]);

}

Ques 16: Write a Program implementing insertion operation in an array.

Ans:

#include<stdio.h>

#include<conio.h>

int i,len,pos,num; void main()

{ int a[100]; void insert(int a[], int, int, int); clrscr(); printf("Enter integers to be read"); scanf("%d",&len); printf("Enter integers");

for(i=0;i<=len;i++)

{

} scanf("%d",&a[i]); printf("Enter integer to be inserted"); scanf("%d",&num); printf("Enter position in the array for insertion"); scanf("%d",&pos);

--pos; insert(a,len,pos,num);

} void insert (int a[], int len, int pos, int num)

{

for(i=len;i>=pos;i--)

{ a[i+1]=a[i];

} a[pos]=num;

if(pos>len)

{

} printf("insertion outside the array"); len++; printf("New array"); for(i=0;i<len;i++)

{ printf("%d\n",a[i]);

} getch();

}

Ques 17: How can we print the address of a particular element in an array?

Ans:

#include<stdio.h>

#include<conio.h> void main()

{

int num[ ]={10,20,30,40,50,60},i; clrscr(); i=0; while(i<=5)

{ printf("ADDRESS = %u ",num[i]); printf("ELEMENT = %d\n ",num[i]); i++;

} getch();

}

Ques 18: Run Time Memory Allocation is known as ?

Ans: Allocating memory at runtime is called a dynamically allocating memory. In this, you dynamically allocate memory by using the new operator when declaring the array, for example : int grades[] = new int[10];

Ques19: What are the types of array operations?

Ans: The following are the operations which can be performed on an array:

Insertion, Deletion, Search, Sorting, Merging, Reversing and Traversal.

Ques 20: How can we print the address of a particular element in a matrix using pointers?

Ans:

#include<stdio.h>

#include<conio.h> main()

{ static int a[3][2] = {

};

{100,200},

{300,400},

{500,600} int *ptr1,i,j,n,m; clrscr(); ptr1=&a[0][0]; n=3; m=2; for(i=0;i<=n-1;i++)

{ printf("\n"); for(j=0;j<=m-1;j++)

{

printf("%d\t",*ptr1); ptr1++;

}} getch();

}

Ques 21: What are the types of matrix operations?

Ans: The following are the types of matrix operations:

Addition, multiplication, transposition, finding determinant of square matrix, subtraction, checking whether it is singular matrix or not etc.

Ques 22: Whether Array is an lvalue or not?

Ans: An lvalue was defined as an expression to which a value can be assigned. Is an array an expression to which we can assign a value? The answer to this question is no, because an array is composed of several separate array elements that cannot be treated as a whole for assignment purposes.

The following statement is therefore illegal: int x[5], y[5]; x = y;

Additionally, you might want to copy the whole array all at once. You can do so using a library function such as the memcpy() function, which is shown here: memcpy(x, y, sizeof(y));

It should be noted here that unlike arrays, structures can be treated as lvalues. Thus, you canassign one structure variable to another structure variable of the same type, such as this: typedef struct t_name

{ char last_name[25]; char first_name[15]; char middle_init[2];

} NAME;

NAME my_name, your_name;

... your_name = my_name;

Ques 23: What is a matrix? Explain its uses with an example

Ans: A matrix is a representation of certain rows and columns, to persist homogeneous data. It can also be called as double-dimensioned array.

Uses:

- To represent class hierarchy using Boolean square matrix

- For data encryption and decryption

- To represent traffic flow and plumbing in a network

- To implement graph theory of node representation

Ques 24: Write the syntax for multiplication of matrices?

Ans: Syntax:

for (=0; < value;++)

{ for (=0; < value;++)

{ for (=0; < value;++)

{ arr[var1][var2] += arr[var1][var3] * arr[var3][arr2];

}

}

}

Ques 25: What are the limitations of arrays?

Ans:The following are the limitations of arrays:

Arrays are of fixed size.

-Data elements are stored in continuous memory locations which may not be available always.

Adding and removing of elements is problematic because of shifting the locations.

Ques 26: Give the complexity in tems of Big O notation for the following algorithmic equations

?

(a) 5.n^2 – 6n + 2 (b)6.2^n + 6

Ans. (a) O(n^2)

(b) O(2^n)

Ques 27. Arrange the following in increasing order of time complexity ?

O(1) , O(2^n) , O(n^2), O(nlogn), O(n^3), O(n), O(logn)

Ans. O(1)< O(logn)< O(n)< O(nlogn)< O(n^2)< O(n^3)< O(2^n)

Ques 28. What do you understand by term O in Big O notation ?

Ans. O(g(n)) = {f(n) : there exists positive constants c , n0 such that 0 <= f(n)<= cg(n) for all n}

Searching , Sorting

Ques 1: What is sequential search? What is the average number of comparisons in a sequential search?

Ans: Sequential search: Searching an element in an array, the search starts from the first element till the last element.The average number of comparisons in a sequential search is (N+1)/2 where N is the size of the array. If the element is in the 1st position, the number of comparisons will be 1 and if the element is in the last position, the number of comparisons will be N.

Ques 2:What is binary searching and Fibonacci search?

Ans: Binary Search: 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.

Ques 3: Explain the bubble sort algorithm.

Ans: Bubble sort algorithm is used for sorting a list. It makes use of a temporary variable for

swapping. It compares two numbers at a time and swaps them if they are in wrong order. This process is repeated until no swapping is needed. The algorithm is very inefficient if the list is long.

E.g. List: - 7 4 5 3

1. 7 and 4 are compared

2. Since 4 < 7, 4 is stored in a temporary variable.

3. the content of 7 is now stored in the variable which was holding 4

4. Now, the content of temporary variable and the variable previously holding 7 are swapped.

121. What is the quickest sorting method to use?

The answer depends on what you mean by quickest. For most sorting problems, it just doesn't matter how quick the sort is because it is done infrequently or other operations take significantly more time anyway. Even in cases in which sorting speed is of the essence, there is no one answer. It depends on not only the size and nature of the data, but also the likely order. No algorithm is best in all cases.

There are three sorting methods in this author's toolbox that are all very fast and that are useful in different situations. Those methods are quick sort, merge sort, and radix sort.

Ques 4: The Quick Sort

Ans: The quick sort algorithm is of the divide and conquer type. That means it works by reducing a sorting problem into several easier sorting problems and solving each of them. A dividing value is chosen from the input data, and the data is partitioned into three sets: elements that belong before the dividing value, the value itself, and elements that come after the dividing value. The partitioning is performed by exchanging elements that are in the first set but belong in the third with elements that are in the third set but belong in the first Elements that are equal to the dividing element can be put in any of the three sets the algorithm will still work properly.

Ques 5: The Merge Sort

Ans: The merge sort is a divide and conquer sort as well. It works by considering the data to be sorted as a sequence of already-sorted lists (in the worst case, each list is one element long).

Adjacent sorted lists are merged into larger sorted lists until there is a single sorted list containing all the elements. The merge sort is good at sorting lists and other data structures that are not in arrays, and it can be used to sort things that don't fit into memory. It also can be implemented as a stable sort.

Ques 6: Write a program implementing Bucket Sorting

Ans:

#include<stdio.h>

#include<conio.h>

#define max 100 int a[max],n,i; void main()

{ void input(void);

clrscr(); input(); getch();

} void input(void)

{ void output(int a[],int n); void radix_sort(int a[],int n); printf("How many elements in the array : "); scanf("%d",&n); printf("\n"); printf("Enter the elements : \n"); for(i=0;i<=n-1;i++)

{ scanf("%d",&a[i]);

} radix_sort(a,n); printf("Sorted Array : \n"); output(a,n);

} void radix_sort(int a[], int n)

{ int bucket[10][5],buck[10],b[10]; int i,j,k,l,num,div,large,passes; div=1; num=0; large=a[0]; for(i=1;i<n;i++)

{ if(a[i]>large) large=a[i];

} while(large>0)

{ num++; large=large/10;

} for(passes=0;passes<num;passes++)

{ for(k=0;k<10;k++) buck[k]=0; for(i=0;i<n;i++)

{ l=(a[i]/div)%10; bucket[l][buck[l]++]=a[i];

} i=0;

for(k=0;k<10;k++)

{ for(j=0;j<buck[k];j++) a[i++]=bucket[k][j];

} div*=10;

}

}

Ques 7: How can I search for data in a linked list?

Ans:Unfortunately, the only way to search a linked list is with a linear search, because the only way a linked list's members can be accessed is sequentially. Sometimes it is quicker to take the data from a linked list and store it in a different data structure so that searches can be more efficient.

Ques 8: What is the heap?

Ans:The heap is where malloc(), calloc(), and realloc() get memory.

Getting memory from the heap is much slower than getting it from the stack. On the other hand, the heap is much more flexible than the stack. Memory can be allocated at any time and deallocated in any order. Such memory isn't deallocated automatically; you have to call free().

Recursive data structures are almost always implemented with memory from the heap. Strings often come from there too, especially strings that could be very long at runtime. If you can keep data in a local variable (and allocate it from the stack), your code will run faster than if you put the data on the heap. Sometimes you can use a better algorithm if you use the heap faster, or more robust, or more flexible. Its a tradeoff.

If memory is allocated from the heap, its available until the program ends. That's great if you remember to deallocate it when you're done. If you forget, it's a problem. A memory leak is some allocated memory that's no longer needed but isn't deallocated. If you have a memory leak inside a loop, you can use up all the memory on the heap and not be able to get any more. (When that happens, the allocation functions return a null pointer.) In some environments, if a program doesn't deallocate everything it allocated, memory stays unavailable even after the program ends.

Ques 9: What is the easiest sorting method to use?

Ans:The answer is the standard library function qsort(). It's the easiest sort by far for several reasons:

It is already written.

It is already debugged.

It has been optimized as much as possible

Void qsort(void *buf, size_t num, size_t size, int (*comp)(const void *ele1, const void *ele2));

Ques 10:Sort the given values using Quick Sort?

65 70 75 80 85 60 55 50 45

Ans:

Sorting takes place from the pivot value, which is the first value of the given elements, this is marked bold. The values at the left pointer and right pointer are indicated using L and R respectively.

65 70

L

75 80 85 60 55 50 45

R

Since pivot is not yet changed the same process is continued after interchanging the values at

L and R positions

65 45 75

L

80 85 60 55 50

R

70

65 45 50 80

L

85 60 55

R

75 70

65 45 50 55 85

L

60

R

80 75 70

65 45 50 55 60

R

85

L

80 75 70

When the L and R pointers cross each other the pivot value is interchanged with the value at right pointer. If the pivot is changed it means that the pivot has occupied its original position in the sorted order (shown in bold italics) and hence two different arrays are formed, one from start of the original array to the pivot position-1 and the other from pivot position+1 to end.

60

L

45 50 55

R

65 85

L

80 75 70

R

55

L

5 45 50

R

60 65 70

R

80

L

75 85

50

L

45

R

55 60 65 70 80

L

75

R

85

In the next pass we get the sorted form of the array.

45 50 55 60 65 70 75 80 85

Ques 11:Explain quick sort and merge sort algorithms.

Ans: Quick sort employs the ‘divide and conquer’ concept by dividing the list of elements into two sub elements

The process is as follows:

1. Select an element, pivot, from the list.

2. Rearrange the elements in the list, so that all elements those are less than the pivot are arranged before the pivot and all elements those are greater than the pivot are arranged after the pivot. Now

the pivot is in its position.

3. Sort the both sub lists – sub list of the elements which are less than the pivot and the list of elements which are more than the pivot recursively.

Merge Sort: A comparison based sorting algorithm. The input order is preserved in the sorted output.

Merge Sort algorithm is as follows:

1.The length of the list is 0 or 1, and then it is considered as sorted.

2. Other wise, divide the unsorted list into 2 lists each about half the size.

3. Sort each sub list recursively. Implement the step 2 until the two sub lists are sorted.

4. As a final step, combine (merge) both the lists back into one sorted list.

Ques 12:What is merge sort algorithm?

Ans: A merge sort algorithm that splits the items to be sorted into two groups, recursively sorts each group, and merges them into a final, sorted sequence. Run time is T(n log n).

If n<2 then the array is already sorted. Stop now.

Otherwise, n>1, and we perform the following three steps in sequence:

Sort the left half of the the array.

Sort the right half of the the array.

Merge the now-sorted left and right halves.

Ques 13: What is Bubble Sort and Quick sort?

Ans: Bubble Sort: The simplest sorting algorithm. It involves the sorting the list in a repetitive fashion. It compares two adjacent elements in the list, and swaps them if they are not in the designated order. It continues until there are no swaps needed. This is the signal for the list that is sorted. It is also called as comparison sort as it uses comparisons.

Quick Sort: The best sorting algorithm which implements the ‘divide and conquer’ concept. It first divides the list into two parts by picking an element a ’pivot’. It then arranges the elements those are smaller than pivot into one sub list and the elements those are greater than pivot into one sub list by keeping the pivot in its original place.

LINKED LISTS

Ques 1:How to find middle node of singly linked list in c?

Ans: Go through the entire linked list incrementing a counter each time. Then with that counter you'll know exactly where the middle is (assuming no nodes have been inserted between the first time you go through it and when you check for the middle)

For example, you can have two node variables to have middle node values, let mid1 and mid2 (in case of even number of total nodes you will have two middle nodes). Now when you visit the first node (i.e. I assume counter =1) then copy this as mid1. then when counter =2 then copy this as mid2.

Now every time you get an odd count, you can move the mid1 one data forward to have the middle node and at just succeeding step when you find an even count, you can move the mid2 one data forward.

In this way, you will always have a copy of middle node and by the time you finish a single traverse you will have the middle node copied in mid1 (if total count is odd), or copied in mid1 and mid2 (if total count is even).

The following function would have to be a member of that class. This returns the data in the middle node, but it shouldn't be too difficult to adapt it to return a pointer to the the node, or whatever else you want to do with the middle node. First here are some explanations about the function:

"Type" is whatever data type your list holds,

"nodeType" is whatever you named the node class you're list uses.

"link" is the node member pointer that points to the next node,

"info" is the node member containing the data.

"first" is the list's pointer to the first node.

Type& findMiddleNode()

{

int check = 0;

nodeType *current;

nodeType *mid;

current = first;

mid = first;

while (current != NULL)

{

current = current->link;

check = (check + 1) % 2;

if (check == 0)

mid = mid->link;

}

return mid->info;

}

Ques 2:Which of the following: singly-linked list or doubly-linked list implementations are more complex?

Ans: Doubly linked lists are complex. This is because the nodes in these Doubly Linked Lists will have a data part and two address parts. These address parts are to be linked with previous and next nodes.

......... node1...................................…

|address--data--address| <==> |address--data--address|

(note the double link between two nodes

But in single linked lists, the nodes contain one data part and one address part. The address part links to next node.

........... node1..............node2............... node3

|data--address| -- >|data--address| --> |data--address|

(note the single link between nodes

So, this implies that double work has to be done when implementing doubly linked lists.

Singly linked lists data structures are two parts, a data part and a pointer part. Thus you can imagine the implementation as a train that you can visit car by car, but only in one direction.

Say your singly linked list is sorted incrementally and you want to insert a new data value. You would go down the train car by car until you finally find the value that is greater than the new data you wish to insert. Unfortunately, you cannot go backwards to insert the new data and you would need to start from the head of the list again to find the node before it for insertion. Possile solutions?

Use two pointers, one in front to compare and one in back to insert. Another solution is to compare the new data value with the data one ahead of the current node. Each has edge cases to resolve (right a the beginning an one at the end. With the doubly link list, you add an extra pointer to point to the previous data node. However, insertions are much easier to deal with. Since you have back pointer, you don't need to keep track of the previous node pointer. The same goes for deleting nodes

In conclusion, singly linked lists are simple structures but more complex to implement. Doubly linked lists are are a little more complex in terms of structure, but the algorithm implementation is a lot easier.

Ques 3:What are the differences between singly-linked doubly-linked and circularly-linked lists?

Ans: The difference is how many pointers each node has, and what they are pointing to. A linked list is comprised of "Nodes" each node contains data as well as 1 or more pointers. A singly linked list has one pointer per node, and a doubly linked list has 2 pointers per node. Some programs use several pointers per node. The purpose of these pointers is to hold the list together. In a singly linked list, you can view a node and can then move on to the next node that it is pointing to until you've passed through them all. A doubly-linked list would have a pointer to the next node as well as to the previous node. Thus you can move forward and backward through the list. A circularly-linked list doesn't necessarily have a set number of pointers because it simply means that the last node points to the first node creating a big circle. A non-circularly-linked list would not contain this last to first pointer and thus you would eventually reach the end of the list and stop.

Ques 4: Write functions Insert and Remove which add and remove nodes from ordered single linked list based on the Node value”

?

Ans: Operations of insertion and deletion in linked list require simple pointer change, so modifying recursive list traversal we can write a solution as following: public Node Insert(Node head, int value)

02. {

03. if (head == null || value < head.value)

04. return new Node(value, head);

05. else

06. {

07. head.next = Insert(head.next, value);

08. return head;

09. }

10. } public Node Remove(Node head, int value)

02. {

03. if (head == null)

04. return null;

05. else

06. if (head.value == value)

07. return head.next;

08. else

09. {

10. head.next = Remove(head.next, value);

11. return head;

12. }

13. }

Ques 5:Write a function which will test whether or not there is a cycle in a single linked list”

?

Ans: There are number of ways to solve this problem and it is really good opportunity to showcase your problem solving skills and knowledge of common data structures and algorithms. The most common and well known approach is based on Floyd’s cycle-finding algorithm published in the

Journal of ACM (JASM), V12, I4 in 1967. The idea is to use 2 pointers first and second initialized to the head. Then traverse the two pointers starting from the head, with first moving 1 node at a time and second moving 2 nodes at a time. If there is indeed a cycle, the nodes will meet inside the loop, otherwise they will reach the tail.

Solution 1. Floyd’s cycle-finding algorithm public bool hasLoop(Node head)

02. {

03. Node first = head;

04. Node second = head;

05. while (first && second &&

06. first.Next && second.Next &&

07. second.Next.Next)

08. {

09. first = first.Next;

10. second = second.Next.Next;

11. if (first == second)

12. {

13. // Found loop

14. return true;

15. }

16. }

17. return false;

18. }

Solution 2. Reverse based algorithm.

If there are no requirements on using extra memory and keeping the list in its original state very neat and simple approach can be uses. The idea is based on the fact that if you reverse the list which has loops you will end-up on the head node while if list doesn’t have loops you will stop at the tail.

01.public bool hasLoop(Node head)

02. {

03. Node first=null;

04. Node second=null;

05. Node tmp=head;

06.

07. while(tmp)

08. {

09. first=second;

10. second=tmp;

11. tmp=tmp.Next;

12. if(tmp==head) return true;

13. second.Next=first;

14. }

15.

16. return false;

17. }

Ques 6:Explain any two advantages using Single linked list over Doubly linked list and viceversa?

Ans: Advantages of single linked list:

1. Decrease in storage space per linked list node

2. Simpler implementation

Advantages of double linked list

1. Decrease in work when accessing a random node

2. Decrease in work when inserting or deleting a node

Ques 7:When to use plain, linked and doubly linked list.?

Ans: Plain

Stores each item sequentially, so random lookup is extremely fast (i.e. I can instantly say "I want the

657415671567th element, and go straight to it, because we know its memory address will be exactly

657415671567 bigger than the first item). This has little or no memory overhead in storage.

However, it has no way of automatically resizing - you have to create a new array, copy across all the values, and then delete the old one. Plain lists are useful when you need to lookup data from anywhere in the list, and you know that your list will not be longer than a certain size.

Linked

Each item has a reference to the next item. This means that there is some overhead (to store the reference to the next item). Also, because they're not stored sequentially, you can't immediately go to the 657415671567th element - you have to start at the head (1st element), and then get its reference to go to the 2nd, and then get its reference, to get to the third, ... and then get its reference to get to the 657415671566th, and then get its reference to get to the 657415671567th. In this way, it is very inefficient for random lookup. However, it allows you to modify the length of the list. If your task is to go through each item sequentially, then it's about the same value as a plain list. If you need to change the length of the list, it could be better than a plain list. If you know the 566th element, and you're looking for the 567th, then all you need to do is follow the reference to the next one.

However, if you know the 567th and you're looking for the 566th, the only way to find it is to start searching from the 1st element again. This is where Double Linked Lists come in handy...

Doubly linked list

Double linked lists store a reference to the previous element. This means you can traverse the list

backwards

as well as forwards. This could be very useful in some situations (such as the example given in the Linked List section). Other than that, they have most of the same advantages and disadvantages as a Linked List.

Ques 8:Write an program to count number of nodes in a singly linked list?

Ans: int Length(struct node* head) {

int count = 0;

struct node* current = head;

while (current != NULL) {

count++;

current = current->next;

}

return(count);

}

Ques 9:Write an efficient C/C++ program to reverse a singly linked list?

Ans: Node* ReverseList( Node * List ) {

Node * list1 = List;

Node * revList = NULL;

Node * temp = NULL;

while ( list1 ) {

temp = list1;

list1 = list1->pNext;

temp->pNext = revList;

revList = temp;

}

return revList;

}

Ques 10:Write an efficient C/C++ program to check whether a linked list has a loop

Ans: boolean CheckIsItCircular(Node *list) {

Node * list1 = list;

Node * list2 = list;

while(list2) {

list1 = list1 -> next;

list2 = list2 -> next;

if(list2) list2 = list2 -> next;

else return false;

(list1 == list2) ) return true;

}

return false;

}

Ques 11:How can you find the nodes with repetetive data in a linked list?

Ans: void findDuplicates(Node *list) {

Node * first = list;

Node * second;

while (first) {

second = first;

second = second -> next;

while (second) {

if(second -> data == first -> data) {

print ("%d", second ->data); \\assume data is integer

}

second = second -> next;

}

first = first -> next;

}

}

Ques 12:Write a function to remove the nodes with repetetive data in a linked list?

Ans: void removeDuplicates(Node *list) {

Node * first = list;

Node * second;

Node * pre;

while (first) {

second = first;

pre = first;

second = second -> next;

while (second) {

if(second -> data == first -> data) {

pre -> next = second -> next;

print ("%d", second ->data); \\ assume data is integer

free (second);

second = pre;

}

pre = second;

second = second -> next;

}

first = first -> next;

}

}

Ques 13:Write a function to swap every second node. [ie - 1->2->3->4->5->| becomes 2->1->4-

>3->5->|]

Ans: Recursive Method in C++:

List * SwapAlternate(List * head) {

if(head == null) return head;

if(head -> next == null) return head;

List * temp = head->next;

List * temp1 = null;

temp1 = SwapAlternate(head->next->next);

head -> next = temp1;

temp -> next = head;

return temp;

}

Ques 14:Sort a linked list

Ans: void Sort( Node *Head) {

node* first,second,temp;

first= Head;

temp = new node();

while(first!=null) {

second=first->NEXT;

while(second!=null) {

if(first->value < second->value) {

temp->value=first->value;

first->value=second->value;

second->value=temp->value;

}

second=second->NEXT;

}

first=first->NEXT;

}

delete temp;

}

Ques 15:Write a function to Insert a node into sorted linked list?

Ans: void sortedInsert(Node * head, Node* newNode) {

Node *current = head;

Node *pre = NULL;

// traverse the list until you find item bigger the new node value

while (current!= NULL && current->data <newNode->data) {

pre = current;

current = current->next;

}

// insert the new node before the big item

newNode->next = current;

if(pre != NULL)

pre->next = newNode;

else

head = newNode;

}

Ques 16:Write a function to return Nth node from the end of the linked list?

Ans: Node * GetNthNodeFromEnd ( Node* Head , int N ) {

Node * pthNode = NULL;

Node * tempNode = NULL;

int currentElement = 0;

for ( tempNode = Head; tempNode != NULL; tempNode = tempNode->Next ) {

currentElement++;

if ( currentElement - N == 0 )

pthNode = Head;

else if ( nCurrentElement - N > 0)

pthNode = pthNode ->Next;

}

if (pthNode)

return pthNode;

else

return NULL;

}

Other improved Method

Node * GetNthNodeFromEnd ( Node* Head , int N ) {

Node * temp=Head, *nthNodeFromEnd = NULL;

int i;

for(i=0; i<N-1 && temp; ++i) {

temp = temp->next;

}

if(temp == null) {

return NULL;

}

else {

nthNodeFromEnd = Head;

temp = temp -> next;

}

while(temp) {

nthNodeFromEnd = nthNodeFromEnd->next;

temp = temp->next;

}

return nthNodeFromEnd;

}

Ques 17:What is the disadvantages of circular linked list over linear linked list?

Ans: First, the assumption is that the question is indeed about circular vs linear lists, as opposed to uni-directional vs bi-directional lists.

A linear list is one that holds no valid, but in fact a designated invalid, value for the reference to the last item's successor, and the first item's predecessor. The name for this invalid reference value is subject to the implementation language, typically NULL, nil or nul.

A circular list only uses valid reference values. Two forms of rings exist: the closed ring and the sentinel ring.

The closed is one where the last item's successor references the first item, and the first item's predecessor refererences the last item.

A characteristic feature of closed rings is that the algorithm cannot normally stop iterating on an

"end reached" criterion. There will be different criteria, subject to the algorithm. A closed ring can never be empty, but it can go in and out of existance.

A sentinel ring is one that contains one artificial element, the sentinel. This item acts as the anchor, as the last item's successor, and the first item's predecessor. A sentinel ring has the a well-defined start and stop (whenever iteration reaches the sentinel). The sentinel is an empty ring's only element.

The reliable existance of the sentinel rids the ring of any invalid references; a useful aspect in the

design of robust software.

Ques 18:How can delete a last node in doubly linked list in c?

Ans :You can delete the last node from a doubly linked list by traversing till the previous node of the last node and set the last node address into a pointer, after that update its previous node's next address to the First Node and change First Node's Previous address to the Last Node's previous node. After updating the Previous and Next Fields of First and Previous node of last node, release the memory of last node using free function.

[Address of Nod4]<=Node1 =><= Node2 =><= Node3 =><= Node4 => [Address of Node1]

Set Node3's Next to Node1 and Node1's Previous to Node3, Free (Node4)

1. Go to the Node3,Stay there

2. Store the Address of Last Node (i.e Node4) to a variable

3. Update the Next Field of Node3 to Node1

4. Update the First Node's (i.e Node1) Previous Field to Node 3

5. Delete the Node4 using free() void DeleteLast(node *head)

{ node *p,*q; for(p=head;p->next->next!=head;p=p->next); /*p Points Node3*/ q=p->next; /*q Points Node4 (i.e Last node)*/ p->next=q->next; /*Update the p's next field to head i.e q's current next field*/ head->previous=q->previous; /* Update the previous field of head to p*/ free(q); /*Free q (Last Node-node4) */

} head is the pointer to the first node. here i am providing a function by which you can delete any position node in double link list.... void delByPos()

{ struct node *p =start; int non=0,i,pos; if(start==NULL)

{ printf("\nEmpty LINK lIST"); return;

} printf("\nEnter the POSITION which is to be deleted");

scanf("%d",&pos); while(p!=NULL)

{ non++; p=p->next;

} p=start; if(pos<1||pos>non);

{ printf("\n INvalid Position");

} if(start==last&&pos==1)

{ free(p); start=last=NULL; printf("\nNODE DEleted"); return;

} else if (pos==1)

{ start=start->next; start->pre=NULL; free(p); printf("\nNOde DELeted"); return;

} else if(pos==non)

{ p=last; last=last->pre; last->next=NULL; free(p); printf("\nNOde DELeted"); return;

} for(i=0;i

{ p=p->next;

} p->pre->next=p->next; p->next->pre=p->pre; free(p); printf("\nNOde DELeted");

}

Ques 19:What is the disadvantages of circular linked list over linear linked list?

Ans :First, the assumption is that the question is indeed about circular vs linear lists, as opposed to uni-directional vs bi-directional lists.

A linear list is one that holds no valid, but in fact a designated invalid, value for the reference to the last item's successor, and the first item's predecessor. The name for this invalid reference value is subject to the implementation language, typically NULL, nil or nul.

A circular list only uses valid reference values. Two forms of rings exist: the closed ring and the sentinel ring.

The closed is one where the last item's successor references the first item, and the first item's predecessor refererences the last item.

A characteristic feature of closed rings is that the algorithm cannot normally stop iterating on an

"end reached" criterion. There will be different criteria, subject to the algorithm. A closed ring can never be empty, but it can go in and out of existance.

A sentinel ring is one that contains one artificial element, the sentinel. This item acts as the anchor, as the last item's successor, and the first item's predecessor. A sentinel ring has the a well-defined start and stop (whenever iteration reaches the sentinel). The sentinel is an empty ring's only element.

The reliable existance of the sentinel rids the ring of any invalid references; a useful aspect in the design of robust software.

Ques 20:How the Doubly Linked List related with Circular Linked List?

Ans: A doubly linked list is a linked list in which each node knows where both of its neighbors are.

A circular linked list is a linked list in which the "tail" of the list is linked to the "root". (Note that both the tail and root of the list are undefined/arbitrary in a circular linked list)

Doubly linked lists are actually not necessarily related to circular linked list (aside from both being based on a linked list structure). In fact, you can have a circular doubly linked list, where each node knows where both of its neighbors are and where the list wraps around to connect to itself.

Ques 21:How to check whether a linked list is circular?

Ans :Consider home pointer as the starting pointer of the linked list. consider temp as the temporary pointer. temp = home; while(temp != NULL)

{

if(temp -> next == start)

{

flag = 1;

break;

}

else

flag = 0; temp = temp -> next;

} if(flag == 1)

printf("Circular"); else

printf("Not circular");

Ques 22:When Should You Use A Linked Lists Instead Of An Array?

Ans: Usually, the data structures you would be deciding between when you are considering a linked list are arrays and linked lists. (ArrayLists are just self-expanding arrays.)

The main considerations are whether you already know how many spaces you will need in your array and whether you require direct access to the elements.

Space

If you need to conserve space while holding an unknown number of elements, linked lists would be looking good. Using the standard double-when-the-array-is-too-small scheme could make you end up using nearly twice as much space as you need; using a linked list will never cause you to reserve unused space.

Direct Access

If you're going to perform a sort on your list, you probably want to use an array, since most sorts jump around between elements as they sort.

If you really want to sort a linked list, bubble sort is probably your best option, since it doesn't require jumping around -- you can just switch the pointers around when you need to swap nodes.

Stack Queue:

Ques 1: What is the data structures used to perform recursion?

Ans: Stack. Because of its LIFO (Last In First Out) property it remembers its 'caller' so knows whom to return when the function has to return. Recursion makes use of system stack for storing the return addresses of the function calls.

Every recursive function has its equivalent iterative (non-recursive) function. Even when such equivalent iterative procedures are written, explicit stack is to be used.

Ques 3: Convert the expression ((A + B) * C - (D - E) ^ (F + G)) to equivalent Prefix and

Postfix notations.

Answer: Prefix Notation: ^ - * +ABC - DE + FG

Postfix Notation: AB + C * DE - - FG + ^

Ques 4:Perform the following conversion from infix to postfix.

a) 2*3/4-5+6

b) A*(B+C)-D/E$(F*G)

Soloution : a) (23*)/4-5+6 = (23*4/)-5+6 = (23*4/5-) +6 = 23*4/5-6+ b) A*(BC+)-D/E$(FG*) = (ABC+*)-D/(EFG*$) = ABC+*DEFG*$/-

Ques 5: Write a recursive C program that find a/b i.e. quotient when a is divided by B.

Solution : int Quotient(int a , int b)

{

If(a<b)

Return 0;

}

Else

Return Quotient (a-b , b) +1;

Ques 7: Evaluate the following expression :

6,2,3,^,+,7,2,/,5,*,-,3,+

Solution :

6,8,+,7,2,/,5,*,-,3,+

14,7,2,/,5,*,-,3,+

14,3,5*,-,3,+

14,15,-,3,+

-1,3,+

2

Ques 8: What is the difference between ARRAY and STACK?

STACK follows LIFO. Thus the item that is first entered would be the last removed.

In array the items can be entered or removed in any order. Basically each member access is done using index. No strict order is to be followed here to remove a particular element.

Ques 9: Explain the terms Base case, Recursive case, Binding Time, Run-Time Stack and Tail

Recursion.

Base case:

A case in recursion, in which the answer is known when the termination for a recursive condition is to unwind back.

Recursive Case:

A case which returns to the answer which is closer.

Run-time Stack:

A run time stack used for saving the frame stack of a function when every recursion or every call occurs.

Tail Recursion:

It is a situation where a single recursive call is consisted by a function, and it is the final statement to be executed. It can be replaced by iteration.

Ques 10: Is it possible to insert different type of elements in a stack? How?

Different elements can be inserted into a stack. This is possible by implementing union / structure data type. It is efficient to use union rather than structure, as only one item’s memory is used at a time.

Ques 11: Explain the three applications in which stacks are used?

The first application majorly deals with the recursion, the second application is a classical and the last one is known as stack machines which chiefly deals with insertion and deletion from the stack.

Ques 12: What does isEmpty() member method determines?

isEmpty() checks if the stack has at least one element. This method is called by Pop() before retrieving and returning the top element.

Ques 13:Describe stack operation.

Answer

Stack is a data structure that follows Last in First out strategy.

Stack Operations:-



Push – Pushes (inserts) the element in the stack. The location is specified by the pointer.



Pop – Pulls (removes) the element out of the stack. The location is specified by the pointer



Swap: - the two top most elements of the stack can be swapped



Peek: - Returns the top element on the stack but does not remove it from the stack



Rotate:- the topmost (n) items can be moved on the stack in a rotating fashion

A stack has a fixed location in the memory. When a data element is pushed in the stack, the pointer points to the current element.

Ques 14: Describe queue operation.

Queue is a data structure that follows First in First out strategy.

Queue Operations:



Push – Inserts the element in the queue at the end.



Pop – removes the element out of the queue from the front



Size – Returns the size of the queue



Front – Returns the first element of the queue.



Empty – to find if the queue is empty.

Ques 15:Discuss how to implement queue using stack.

A queue can be implemented by using 2 stacks:-



1. An element is inserted in the queue by pushing it into stack 1



2. An element is extracted from the queue by popping it from the stack 2



3. If the stack 2 is empty then all elements currently in stack 1 are transferred to stack 2 but in the reverse order



4. If the stack 2 is not empty just pop the value from stack 2.

Ques 16: What is the difference between a stack and a Queue?

Stack –

Represents the collection of elements in Last In First Out order.

Operations includes testing null stack, finding the top element in the stack, removal of top most element and adding elements on the top of the stack.

Queue -

Represents the collection of elements in First In First Out order.

Operations include testing null queue, finding the next element, removal of elements and inserting the elements from the queue.

Insertion of elements is at the end of the queue

Deletion of elements is from the beginning of the queue.

Ques 17:What are priority queues?

Answer

A priority queue is essentially a list of items in which each item has associated with it a priority

Items are inserted into a priority queue in any, arbitrary order. However, items are withdrawn from a priority queue in order of their priorities starting with the highest priority item first.

Priority queues are often used in the implementation of algorithms

Ques 18:How is the front of the queue calculated ?

The front of the queue is calculated by front = (front+1) % size.

Ques 19:Minimum number of queues needed to implement the priority queue?

Answer: Two. One queue is used for actual storing of data and another for storing priorities

Stack Queue:

Ques 1: What is the data structures used to perform recursion?

Ans: Stack. Because of its LIFO (Last In First Out) property it remembers its 'caller' so knows whom to return when the function has to return. Recursion makes use of system stack for storing the return addresses of the function calls.

Every recursive function has its equivalent iterative (non-recursive) function. Even when such equivalent iterative procedures are written, explicit stack is to be used.

Ques 3: Convert the expression ((A + B) * C - (D - E) ^ (F + G)) to equivalent Prefix and

Postfix notations.

Answer: Prefix Notation: ^ - * +ABC - DE + FG

Postfix Notation: AB + C * DE - - FG + ^

Ques 4:Perform the following conversion from infix to postfix.

a) 2*3/4-5+6

b) A*(B+C)-D/E$(F*G)

Soloution : c) (23*)/4-5+6 = (23*4/)-5+6 = (23*4/5-) +6 = 23*4/5-6+ d) A*(BC+)-D/E$(FG*) = (ABC+*)-D/(EFG*$) = ABC+*DEFG*$/-

Ques 5: Write a recursive C program that find a/b i.e. quotient when a is divided by B.

Solution : int Quotient(int a , int b)

{

}

If(a<b)

Return 0;

Else

Return Quotient (a-b , b) +1;

Ques 7: Evaluate the following expression :

6,2,3,^,+,7,2,/,5,*,-,3,+

Solution :

6,8,+,7,2,/,5,*,-,3,+

14,7,2,/,5,*,-,3,+

14,3,5*,-,3,+

14,15,-,3,+

-1,3,+

2

Ques 8: What is the difference between ARRAY and STACK?

STACK follows LIFO. Thus the item that is first entered would be the last removed.

In array the items can be entered or removed in any order. Basically each member access is done using index. No strict order is to be followed here to remove a particular element.

Ques 9: Explain the terms Base case, Recursive case, Binding Time, Run-Time Stack and Tail

Recursion.

Base case:

A case in recursion, in which the answer is known when the termination for a recursive condition is to unwind back.

Recursive Case:

A case which returns to the answer which is closer.

Run-time Stack:

A run time stack used for saving the frame stack of a function when every recursion or every call occurs.

Tail Recursion:

It is a situation where a single recursive call is consisted by a function, and it is the final statement to be executed. It can be replaced by iteration.

Ques 10: Is it possible to insert different type of elements in a stack? How?

Different elements can be inserted into a stack. This is possible by implementing union / structure data type. It is efficient to use union rather than structure, as only one item’s memory is used at a time.

Ques 11: Explain the three applications in which stacks are used?

The first application majorly deals with the recursion, the second application is a classical and the last one is known as stack machines which chiefly deals with insertion and deletion from the stack.

Ques 12: What does isEmpty() member method determines?

isEmpty() checks if the stack has at least one element. This method is called by Pop() before retrieving and returning the top element.

Ques 13:Describe stack operation.

Answer

Stack is a data structure that follows Last in First out strategy.

Stack Operations:-



Push – Pushes (inserts) the element in the stack. The location is specified by the pointer.



Pop – Pulls (removes) the element out of the stack. The location is specified by the pointer



Swap: - the two top most elements of the stack can be swapped



Peek: - Returns the top element on the stack but does not remove it from the stack



Rotate:- the topmost (n) items can be moved on the stack in a rotating fashion

A stack has a fixed location in the memory. When a data element is pushed in the stack, the pointer points to the current element.

Ques 14: Describe queue operation.

Queue is a data structure that follows First in First out strategy.

Queue Operations:



Push – Inserts the element in the queue at the end.



Pop – removes the element out of the queue from the front



Size – Returns the size of the queue



Front – Returns the first element of the queue.



Empty – to find if the queue is empty.

Ques 15:Discuss how to implement queue using stack.

A queue can be implemented by using 2 stacks:-



1. An element is inserted in the queue by pushing it into stack 1



2. An element is extracted from the queue by popping it from the stack 2



3. If the stack 2 is empty then all elements currently in stack 1 are transferred to stack 2 but in the reverse order



4. If the stack 2 is not empty just pop the value from stack 2.

Ques 16: What is the difference between a stack and a Queue?

Stack –

Represents the collection of elements in Last In First Out order.

Operations includes testing null stack, finding the top element in the stack, removal of top most element and adding elements on the top of the stack.

Queue -

Represents the collection of elements in First In First Out order.

Operations include testing null queue, finding the next element, removal of elements and inserting the elements from the queue.

Insertion of elements is at the end of the queue

Deletion of elements is from the beginning of the queue.

Ques 17:What are priority queues?

Answer

A priority queue is essentially a list of items in which each item has associated with it a priority

Items are inserted into a priority queue in any, arbitrary order. However, items are withdrawn from a priority queue in order of their priorities starting with the highest priority item first.

Priority queues are often used in the implementation of algorithms

Ques 18:How is the front of the queue calculated ?

The front of the queue is calculated by front = (front+1) % size.

Ques 19:Minimum number of queues needed to implement the priority queue?

Answer: Two. One queue is used for actual storing of data and another for storing priorities

GRAPHS

Ques 1: Does the minimum spanning tree of a graph give the shortest distance between any 2 specified nodes?

Ans: No. Minimal spanning tree assures that the total weight of the tree is kept at its minimum. But it doesn't mean that the distance between any two nodes involved in the minimum-spanning tree is minimum.

Ques 2: Convert the given graph with weighted edges to minimal spanning tree.

Ans: the equivalent minimal spanning tree is:

Ques 3: What is the difference between BFS and DFS?

Ans : BFS: This can be throught of as being like Dijkstra's algorithm for shortest paths, but with every edge having the same length. However it is a lot simpler and doesn't need any data structures.

We just keep a tree (the breadth first search tree), a list of nodes to be added to the tree, and markings (Boolean variables) on the vertices to tell whether they are in the tree or list.

Depth first search is another way of traversing graphs, which is closely related to preorder traversal of a tree. Recall that preorder traversal simply visits each node before its children. It is most easy to program as a recursive routine:

Ques 4:Write an algorithm to find the shortest path in Graphs ?

Ans: The Floyd–Warshall algorithm compares all possible paths through the graph between each pair of vertices. It is able to do this with only

V

3

comparisons. This is remarkable considering that there may be up to

V

2

edges in the graph, and every combination of edges is tested. It does so by incrementally improving an estimate on the shortest path between two vertices, until the estimate is known to be optimal.

Consider a graph

G

with vertices

V

, each numbered 1 through

N

. Further consider a function shortestPath(

i

,

j

,

k

) that returns the shortest possible path from

i

to

j

using only vertices 1 to

k

as intermediate points along the way. Now, given this function, our goal is to find the shortest path from each

i

to each

j

using only nodes 1 to

k

+ 1.

There are two candidates for this path: either the true shortest path only uses nodes in the set

{1, ...,

k

}; or there exists some path that goes from

i

to

k

+ 1, then from

k

+ 1 to

j

that is better. We know that the best path from

i

to

j

that only uses nodes 1 through

k

is defined by shortestPath(

i

,

j

,

k

), and it is clear that if there were a better path from

i

to

k

+ 1 to

j

, then the length of this path would be the concatenation of the shortest path from

i

to

k

+ 1 (using vertices in {1, ...,

k

} and the shortest path from

k

+ 1 to

j

(also using vertices in {1, ...,

k

}).

Therefore, we can define shortestPath(

i

,

j

,

k

) in terms of the following recursive formula:

This formula is the heart of Floyd–Warshall. The algorithm works by first computing shortestPath(

i

,

j

,

k

) for all (

i

,

j

) pairs, then using that to find shortestPath(

i

,

j

, 2) for all (

i

,

j

) pairs, etc.

This process continues until

k

=

n

, and we have found the shortest path for all (

i

,

j

) pairs using any intermediate vertices.

ALGORITHM:

1 /* Assume a function

edgeCost

(i,j) which returns the cost of the edge from i to j

2 (infinity if there is none).

3 Also assume that

n

is the number of vertices and

edgeCost

(i,i) = 0

4

int

path[][];

5 /* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path

6 from i to j using intermediate vertices (1..k−1). Each path[i][j] is initialized to

7

edgeCost

(i,j) or infinity if there is no edge between

i

and

j

.

8

procedure

FloydWarshall

()

9

for

k := 1

to

n

10

for each

(i, j)

{1, ..., n}

2

11 path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );

Ques 5: Write a single source shortest path algorithm with example?

Ans :

D ijkstra's algorithm solves the single-source shortest-path problem when all edges have nonnegative weights. It is a greedy algorithm and similar to Prim's algorithm. Algorithm starts at the source vertex, s, it grows a tree, T, that ultimately spans all vertices reachable from S. Vertices are added to T in order of distance i.e., first S, then the vertex closest to S, then the next closest, and so on. Following implementation assumes that graph G is represented by adjacency lists.

DIJKSTRA (G, w, s)

INITIALIZE SINGLE-SOURCE (G, s)

S ← { } // S will ultimately contains vertices of final shortest-path weights from s

Initialize priority queue Q i.e., Q ← V[G] while priority queue Q is not empty do

u

← EXTRACT_MIN(Q) // Pull out new vertex

S ← S È {

u

}

// Perform relaxation for each vertex

v

adjacent to u

for each vertex v in Adj[u] do

Relax (

u

,

v

,

w

)

Analysis

Like Prim's algorithm, Dijkstra's algorithm runs in O(|E|lg|V|) time.

Example: Step by Step operation of Dijkstra algorithm.

Step1. Given initial graph G=(V, E). All nodes nodes have infinite cost except the source node, s, which has 0 cost.

Step 2. First we choose the node, which is closest to the source node, s. We initialize d[s] to 0. Add it to S. Relax all nodes adjacent to source, s. Update predecessor (see red arrow in diagram below) for all nodes updated.

Step 3. Choose the closest node, x. Relax all nodes adjacent to node x. Update predecessors for nodes u, v and y (again notice red arrows in diagram below).

Step 4. Now, node y is the closest node, so add it to S. Relax node v and adjust its predecessor (red arrows remember!).

Step 5. Now we have node u that is closest. Choose this node and adjust its neighbor node v.

Step 6. Finally, add node v. The predecessor list now defines the shortest path from each node to the source node, s.

Ques 6:Does dijkstra's algorithm for shortest path provide the optimal solution ?

Ans : Yes,dijkstra's algorithm for shortest path provide the optimal solution.

To find the shortest path between points, the weight or length of a path is calculated as the sum of the weights of the edges in the path. A path is a shortest path is there is no path from x to y with lower weight. Dijkstra's algorithm finds the shortest path from x to y in order of increasing distance from x. That is, it chooses the first minimum edge, stores this value and adds the next minimum value from the next edge it selects. It starts out at one vertex and branches out by selecting certain edges that lead to new vertices. It is similar to the minimum spanning tree algorithm, in that it is

"greedy", always choosing the closest edge in hopes of an optimal solution.

Characteristics of a Shortest Path Algorithm:

Dijkstra's algorithm selects an arbitrary starting vertex and then branches out from the tree constructed so far. Each of the nodes it visits could be in the tree, in the fringes or unseen. The designators:

1)

TREE - nodes in the tree constructed so far

2) FRINGE - not in the tree, but adjacent to some vertex in the tree

3) UNSEEN - all others designate for each node in the graph whether the node is part of the shortest path tree, a part of the set of fringes adjacent to the nodes in the tree or a part of, as of yet, unseen set of graph nodes. A crucial step in the algorithm is the selection of the node from the fringe edge.

The algorithm always takes the edge with least weight from the tree to the fringe node. This is an example of a greedy algorithm which are used in optimization problems. They make locally optimal choices in hope that this will provide a globally optimal solution.

Ques 7:Explain Prim’s Algorithm

.

Ans:

L ike Kruskal's algorithm, Prim's algorithm is based on a generic MST algorithm. The main idea of Prim's algorithm is similar to that of Dijkstra's algorithm for finding shortest path in a given graph. Prim's algorithm has the property that the edges in the set A always form a single tree. We begin with some vertex

v

in a given graph G =(V, E), defining the initial set of vertices A. Then, in each iteration, we choose a minimum-weight edge (

u

,

v

), connecting a vertex v in the set A to the vertex

u

outside of set A. Then vertex

u

is brought in to A. This process is repeated until a spanning tree is formed. Like Kruskal's algorithm, here too, the important fact about MSTs is we always choose the smallest-weight edge joining a vertex inside set A to the one outside the set A. The implication of this fact is that it adds only edges that are safe for A; therefore when the algorithm terminates, the edges in set A form a MST.

Outline of Prim's Algorithm

Choose a node and build a tree from there selecting at every stage the shortest available edge that can extend the tree to an additional node.

Algorithm

MST_PRIM (G,

w

,

v

)

1. Q ← V[G]

2. for each

u

in Q do

3. key [

u

] ← ∞

4. key [

r

] ← 0

5. π[

r

] ← NIl

6. while queue is not empty do

7.

u

← EXTRACT_MIN (Q)

8. for each

v

in Adj[

u

] do

9. if v is in Q and

w

(

u

,

v

) < key [

v

]

10. then π[

v

] ←

w

(

u

,

v

)

11. key [

v

] ←

w

(

u

,

v

)

Analysis

The performance of Prim's algorithm depends of how we choose to implement the priority queue Q.

Definitions

Sparse graphs are those for which |E| is much less than |V|

2

i.e., |E| << |V|

2

we preferred the adjacency-list representation of the graph in this case. On the other hand, dense graphs are those for which |E| is graphs are those for which |E| is close to |V|

2

. In this case, we like to represent graph with adjacency-matrix representation.

Tree

Ques 1: What is a B tree?

Ans

A B-tree of order m (the maximum number of children for each node) is a tree which satisfies the following properties :

1. Every node has <= m children.

2. Every node (except root and leaves) has >= m/2 children.

3. The root has at least 2 children.

4. All leaves appear in the same level, and carry no information.

5. A non-leaf node with k children contains k – 1 keys

Ques 2: Describe Tree database. Explain its common uses.

Ans

A tree is a data structure which resembles a hierarchical tree structure. Every element in the

structure is a node. Every node is linked with the next node, either to its left or to its right. Each node has zero or more child nodes. The length of the longest downward path to a leaf from that node is known as the height of the node and the length of the path to its root is known as the depth of a node.

Common Uses:

- To manipulate hierarchical data

- Makes the information search, called tree traversal, easier.

- To manipulate data that is in the form of sorted list.

- To give visual effects for digital images using as a work flow by compositing them.

Ques 3: What is binary tree? Explain its uses.

Ans:

A binary tree is a tree structure, in which each node has only two child nodes. The first node is known as root node. The parent has two nodes namely left child and right child.

Uses of binary tree:

- To create sorting routine.

- Persisting data items for the purpose of fast lookup later.

- For inserting a new item faster

Ques 4:WRITE A FUNCTION TO IMPLEMENT THE RECURSION PREORDER

TRAVERSAL OF A BINARY SEARCH TREE.

Ans: struct BINARY_S_TREE

{

BINARY_S_TREE *left; int info;

BINARY_S_TREE *right;

};

BINARY_S_TREE *root; void RECURSION_preorder(BINARY_S_TREE * root_loc)

{

BINARY_S_TREE *loc; loc=root_loc; if(loc!=NULL)

{ cout<<loc->info<<"->";

RECURSION_preorder(loc->left);

RECURSION_preorder(loc->right);

}

}

Ques 5: Explain pre-order and in-order tree traversal.

A non-empty binary tree is traversed in 3 types, namely pre-order, in-order and post-order in a recursive fashion.

Pre-order:

Pre-order process is as follows:

- Visit the root node

- Traverse the left sub tree

- Traverse the right sub tree

In-Order:

In order process is as follows:

- Traverse the left sub tree

- Visit the root node

- Traverse the right sub tree

Ques 6: What is a B+ tree? Explain its uses.

B+ tree represents the way of insertion, retrieval and removal of the nodes in a sorted fashion.

Every operation is identified by a ‘key’. B+ tree has maximum and minimum bounds on the number of keys in each index segment, dynamically. All the records in a B+ tree are persisted at the last level, i.e., leaf level in the order of keys.

B+ tree is used to visit the nodes starting from the root to the left or / and right sub tree. Or starting from the first node of the leaf level. A bi directional tree traversal is possible in the B+ tree.

Ques 7:WRITE A FUNCTION TO IMPLEMENT THE CREATION OF A BINARY

SEARCH TREE

.

Ans: struct BINARY_S_TREE

{

BINARY_S_TREE *left; int info;

BINARY_S_TREE *right;

};

BINARY_S_TREE *root; void create(BINARY_S_TREE *loc, int data)

{

BINARY_S_TREE *FRESH; if(data==loc->info)

{ cout<<"DUPLICATE VALUE\n";

return;

} else if(data<loc->info)

{ if(loc->left != NULL)

{ create(loc->left,data);

} else

{

}

} cout<<"INSERTING TO LEFT\n";

FRESH=new BINARY_S_TREE;

FRESH->info=data;

FRESH->left=FRESH->right=NULL; loc->left=FRESH;

{

} else

}

{

} if(loc->right != NULL)

{ create(loc->right,data);

} else cout<<"INSERTING TO RIGHT\n";

FRESH=new BINARY_S_TREE;

FRESH->info=data;

FRESH->left=FRESH->right=NULL; loc->right=FRESH;

Ques 8: Define threaded binary tree. Explain its common uses

A threaded binary tree is structured in an order that, all right child pointers would normally be null and points to the ‘in-order successor’ of the node. Similarly, all the left child pointers would normally be null and points to the ‘in-order predecessor’ of the node.

Uses of Threaded binary tree:

- Traversal is faster than unthreaded binary trees

- More subtle, by enabling the determination of predecessor and successor nodes that starts from any node, in an efficient manner.

- No stack overload can be carried out with the threads.

- Accessibility of any node from any other node

- It is easy to implement to insertion and deletion from a threaded tree.

Ques 9: Explain implementation of traversal of a binary tree.

Binary tree traversal is a process of visiting each and every node of the tree. The two fundamental binary tree traversals are ‘depth-first’ and ‘breadth-first’.

The depth-first traversal are classified into 3 types, namely, pre-order, in-order and post-order.

Pre-order: Pre-order traversal involves visiting the root node first, then traversing the left sub tree and finally the right sub tree.

In-order: In-order traversal involves visiting the left sub tree first, then visiting the root node and finally the right sub tree.

Post-order: Post-order traversal involves visiting the left sub tree first, then visiting the right sub tree and finally visiting the root node.

The breadth-first traversal is the ‘level-order traversal’. The level-order traversal does not follow the branches of the tree. The first-in first-out queue is needed to traversal in level-order traversal.

Ques 10:WRITE A FUNCTION TO IMPLEMENT THE DELETION OF A NODE WITH

TWO CHILDREN FROM BINARY SEARCH TREE.

Ans: struct BINARY_S_TREE

{

BINARY_S_TREE *left; int info;

BINARY_S_TREE *right;

};

BINARY_S_TREE *root; void del_NODE_WITH_2_CHILDS()

{

BINARY_S_TREE *loc,*par,*temp, *ptr, *ptrr, *child; int item; loc=root; cout<<"ENTER THE NODE TO BE DELETED "; cin>>item; while(loc->info != item)

{ if(item < loc->info)

{

} else par=loc; loc=loc->left;

{ par=loc;

}

}

} ptr=loc; loc=loc->right; ptrr=loc->right; while(ptrr->left != NULL)

{ ptr=ptrr; ptrr=ptrr->left; if(ptrr->left == NULL && ptrr->right == NULL)

{ if(ptr->info > ptrr->info)

{

} else ptr->left=NULL;

{

} ptr->right=NULL;

} else if(ptrr->left !=NULL || ptrr->right !=NULL)

{ if(ptrr->left == NULL)

{ child = ptrr->right;

} else

{

} child = ptrr->left; if(ptr->info > ptrr->info)

{

} else ptr->left=child;

{

} ptr->right=child;

} if(par == NULL)

{

} root=ptrr; else if(loc == par->left)

{

} else

{ par->left=ptrr;

} par->right=ptrr; ptrr->left=loc->left; ptrr->right=loc->right; delete loc;

}

Ques 11: Explain implementation of deletion from a binary tree.

To implement the deletion from a binary tree, there is a need to consider the possibilities of deleting the nodes. They are:

- Node is a terminal node: In case the node is the left child node of its parent, then the left pointer of its parent is set to NULL. In all other cases, if the node is right child node of its parent, then the right pointer of its parent is set to NULL.

- Node has only one child: In this scenario, the appropriate pointer of its parent is set to child node.

- Node has two children: The predecessor is replaced by the node value, and then the predecessor of the node is deleted.

Ques 12: List out few of the Application of tree data-structure?

The manipulation of Arithmetic expression, Symbol Table construction, Syntax analysis.

Ques 13: In RDBMS, what is the efficient data structure used in the internal storage representation?

B+ tree. Because in B+ tree, all the data is stored only in leaf nodes, that makes searching easier.

This corresponds to the records that shall be stored in leaf nodes.

1

2

Ques 14: CONSIDER THE ALGEBRIC EXPRESSION E = ( 2x + y )( 5a – b ), DRAW

THE TREE.

Ans: y x

+

-

1

5 b a

Ques 15: What is a spanning Tree?

A spanning tree is a tree associated with a network. All the nodes of the graph appear on the tree once. A minimum spanning tree is a spanning tree organized so that the total edge weight between nodes is minimized.

Does the minimum spanning tree of a graph give the shortest distance between any 2 specified nodes?

Minimal spanning tree assures that the total weight of the tree is kept at its minimum. But it doesn't mean that the distance between any two nodes involved in the minimum-spanning tree is minimum.

Ques 16: Convert the expression ((A + B) * C - (D - E) ^ (F + G)) to equivalent Prefix and

Postfix notations.

Ans: Prefix Notation: ^ - * +ABC - DE + FG

Postfix Notation: AB + C * DE - - FG + ^

Ques 17: How many null branches are there in a binary tree with 20 nodes?

Ans: 21

Let us take a tree with 5 nodes (n=5)

It will have only 6 (ie,5+1) null branches.

A binary tree with n nodes has exactly n+1 null nodes.

Ques 18:WRITE A ALGORITHM TO FIND THE DEPTH OF THE TREE.

Ans: depth(left, right, root, dep)

1.

2.

3.

4.

if root=NULL then set sep=0 and return call depth (left, right, left[root], depl) call depth (left, right, right[root], depr) if depl >= depr then set dep = depl + 1 else set dep = depr + 1

5. return

Ques 19: In an AVL tree, at what condition the balancing is to be done?

Answer: If the 'pivotal value' (or the 'Height factor') is greater than 1 or less than -1.

Ques 20: SUPPOSE A BINARY TREE T IS IN THE MEMORY. WRITE A RECURSIVE

PROCEDURE WHICH FINDS THE NUMBER OF NODES IN T.

Ans:

COUNT (LEFT, RIGHT, ROOT, NUM)

1.

If root=NULL, set num=0 and return call count ( left, right, left[root], numl) 2.

3.

4.

5.

call count ( left, right, right[root], numr) set num=numl+numr+1 return

Ques 21: There are 8, 15, 13, 14 nodes were there in 4 different trees. Which of them could have formed a full binary tree?

Ans: 15.

In general:

There are 2n-1 nodes in a full binary tree.

By the method of elimination:

Full binary trees contain odd number of nodes. So there cannot be full binary trees with 8 or 14 nodes, so rejected. With 13 nodes you can form a complete binarytree but not a full binary tree.

So the correct answer is 15.

Ques 22: In the given binary tree, using array you can store the node 4 at which location?

Ans: At location 6

1 2 3 - - 4 - - 5

Root LC1 RC1 LC2 RC2 LC3 RC3 LC4 RC4 where LCn means Left Child of node n and RCn means Right Child of node n

Ques 23: Draw a binary Tree for the expression : A * B - (C + D) * (P / Q)

Answer:

Ques 24: For the following COBOL code, draw the Binary tree?

01 STUDENT_REC.

02 NAME.

03 FIRST_NAME PIC X(10).

03 LAST_NAME PIC X(10).

02 YEAR_OF_STUDY.

03 FIRST_SEM PIC XX.

03 SECOND_SEM PIC XX.

Answer:

Ques 25: Draw the B-tree of order 3 created by inserting the following data arriving in sequence - 92 24 6 7 11 8 22 4 5 16 19 20 78

Answer:

Ques 26: Does the minimum spanning tree of a graph give the shortest distance between any 2 specified nodes?

Answer: No. Minimal spanning tree assures that the total weight of the tree is kept at its minimum. But it doesn't mean that the distance between any two nodes involved in the minimum-spanning tree is minimum.

Ques 27: Convert the given graph with weighted edges to minimal spanning tree.

Answer: the equivalent minimal spanning tree is:

Ques 28: For the given graph, draw the DFS and BFS?

Answer:



BFS: A X G H P E M Y J



DFS: A X H P E Y M J G

Download