* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Data Structures
Survey
Document related concepts
Transcript
RAMRAO ADIK INSTITUTE OF TECHNOLOGY, NERUL Lab Manual: Data Structures Department of Computer Engg. List of Experiments Name of Faculty: Prof. Vanita Mane Prof. Vimla Jethani Prof. Nazia S Term: Jul 2014 – Oct 2014 Subject: Data Structures Lab Session: 2hr/week Year & Semester: S.E Sem III No. of Lectures per week: 4 No. of Weeks: 15 SR.No. Title 1 Implementation of STRING Functions 2 Implementation of STACK menu driven program 3 Implementation of INFIX to POSTFIX transformation and its evaluation 4 Implementation of CIRCULAR QUEUE menu driven program 5 Implementation of DEQUEUE menu driven program 6 Implementation of SINGLY LINKED LIST 7 Implementation of different operations on linked list: COPY, CONCATENATE, SPLIT, REVERSE, COUNT 8 Implementation of BINARY TREE CREATION AND TRAVERSAL 9 Implementation of CONSTRUCTION of EXPRESSION TREE using POSTFIX EXPRESSION 10 Implementation of BINARY SEARCH TREE (BST) program 11 Implementation of SHELL SORT , INSERTION SORT & RADIX SORT menu driven program 12 Implementation of Searching methods (INDEX SEQUENTIAL, INTERPOLATION SEARCH) menu driven program 13 Implementation of BREADTH FIRST SEARCH & DEPTH FIRST SEARCH Experiment No. 1 Aim: To perform different operations on strings. Theory: Strings represent a sequence of characters. The end of the string is marked with a special character, the null character, which is simply the character with the value 0. The null or string-terminating character is represented by another character escape sequence, „\0’. The C library contains a few basic string manipulation functions.The following are the operations that can be performed on strings String Copy String Concatenate String Compare String Length String Reverse Algorithm: 1. String Copy: This function copies a string, including the null character terminator from the source string to the destination. 1. Initialize n = 0. 2. Repeat step 2 until null character(a[n] = „\0‟) occurs a. Set dest[n] = a[n] b. Set n = n + 1 3. Set dest[n] = \0 4. Return 2. String Concatenate: This function appends a source string to the end of a destination string. 1. Initialize n = 0 and m=0. 2. Repeat step 2 until null character(s1[n] = „\0‟) occurs Set n = n + 1 3. Repeat step 3 until null character(s2[m] = „\0‟) occurs a. Set s1[n] = s2[m] b. Set n = n + 1 c. Set m = m + 1 4. Set s1[n] = \0 5. Return 3. String Compare: This function compares the two strings. 1. Calculate length of string1 and string2 and initialize j = 0 2. Check if length of string1 > length of string2 then set k = length of String1 else set k = length of string2 3. Repeat steps 3 until j < k. a. check if s1[j] = s2[j] then set flag = 0 else set flag = 1 and go to step 4 b. check if flag = 0 then print : “String matches” else print : “Strings are diffirent” 4. Return 4. String Length: This function calculates the length of the string 1.Intialize i=0 2.Intialize counter variable l=0 3.Repeat step 3 until null character(s1[i]!=‟\0‟) a. Set l=l+1 5.Return 5. String Reverse: This function is used to reverse the original string 1. Calculate the length of the string and store it in the variable l 2. Intialize i=0 3. Set s2[l]=‟\0‟ 4. set j=l 5. repeat step 5 until i<l a. set s2[i]=s1[j] b. set j =j-1 6. return Conclusion: Thus we can perform different operations on strings without using any inbuilt function provided by the programming language. Experiment No. 2 Aim: Implementation of STACK menu driven program Theory: A stack is an ordered list in which all insertions and deletions are made at one end, called the top. Given a stack S=(a[1],a[2],.......a[n]) then we say that a1 is the bottommost element and element a[i]) is on top of element a[i-1], 1<i<=n. The restrictions on a stack imply that if the elements A,B,C,D,E are added to the stack, n that order, then the first element to be removed/deleted must be E. Equivalently we say that the last element to be inserted into the stack will be the first to be removed. For this reason stacks are sometimes referred to as Last In First Out (LIFO) lists. Algorithm: 1. Algorithm for Inserting an item into the stack (PUSH) PUSH(maxsize, item) Let stack[maxsize] is an array for implementing the stack. 1. Check for stack overflow If top= maxsize – 1, then print : “Stack Overflow” and return. 2. Set top=top+1 3. Set stack[top]=item 4. return. 2. Algorithm for Deleting an item from the stack (POP) POP(maxsize) 1. Check if top < 0 then print : “Stack Underflow” and return. else set item = stack[top] 2. Set top = top – 1 3. Return the deleted item from the stack Conclusion: Thus we can insert and delete element only at one end using stack data structures. Experiment No. 3 Aim: Implementation of INFIX to POSTFIX transformation and its evaluation Theory: An expression is defined as a number of operands or data items combined using several operators. There are basically three types of notation for an expression, 1. Infix notation 2. Prefix notation 3. Postfix notation The infix notation is what we come across in our general mathematics, where the operator is written in-between the operands. Example: A+B (note that the operator „+‟ is written in-between the operands A and B). The prefix notation is one in which the operator is written before the operands, it is also called polish notation. The same expression when written in prefix notation looks like: +AB (as operator „+‟ is written before operands A and B). In the postfix notation the operators are written after the operands, so it is called postfix notation. It is also known as reverse polish or suffix notation. The above expression if written in postfix expression looks like: AB+ (as operator is written after the operands A and B) The rules to be remembered during infix to postfix conversion are: 1. Parenthesize the expression starting from left to right. 2. During parenthesizing the expression, the operands associated with operator having higher precedence are first parenthesized. 3. The sub-expression (part of expression) which has been converted into postfix is to be treated as single operand. 4. Once the expression is converted to postfix form, remove the parenthesis. Example : A + (B*C) Parenthesized expression (infix form) A + (BC*) Convert the multiplication A (BC*) + Convert the addition ABC*+ Postfix form Algorithm: 1. Algorithm for Infix to Postfix Conversion Suppose Q is an arithmetic expression written in infix notation. This algorithm finds the equivalent postfix expression P. 1. Scan Q from left to right and repeat steps 2 to 4 for each element of Q until the STACK is empty. 2. If an operand is encountered, add it to P 3. If right parenthesis is encountered, then: a. Repeatedly pop from STACK and add to P each operator (on the top of STACK) until a left parenthesis is encountered. b. Remove the left parenthesis ( do not add the left parenthesis to P). 4. If an operator is encountered, then check the precedence of incoming operator with the element present at top of stack. a. if precedence of incoming operator is higher, then push it onto STACK. b. if precedence of incoming operator is less, then b.1 Repeatedly pop from STACK and add to P each operator (on the top of STACK) b.2 Push the incoming operator onto STACK. 5. Pop the remaining elements from STACK and add it to P. 6. Exit. 2. Algorithm for Postfix Evaluation Let postfix [] be an array of postfix expression. 1. Scan postfix from left to right and repeat steps 2 to 5 for each element of infix until the stack is empty. 2. If an operand is encountered, push it onto stack. 3. If an operator is encountered, then: 3.1. Remove top two elements of stack and perform the operation based on operator. 3.2. Evaluate the expression and place the result back to stack. Conclusion: Thus we can convert the given infix expression into postfix and evaluate postfix expression using STACK. Experiment No. 4 Aim: Implementation of CIRCULAR QUEUE menu driven program Theory: A circular queue is one in which the insertion of a new element is done at the very first location of the queue if last location of the queue is full. In other words if we have queue Q of say n elements, then after inserting an element last (i.e., in the n-1th) location of the array the next element will be inserted at the very first location (i.e., location with subscript 0) of the array. It is possible to insert new elements, if and only if those locations (slots) are empty. We can say that a circular queue is one in which the first element comes just after the last element. It can be viewed as a mesh or loop of wire, in which the two ends of the wire are connected together. A circular queue overcomes the problem of unutilized space in linear queues implemented as arrays. A circular queue also have a front and rear to keep the track of the elements to be deleted and inserted and therefore to maintain the unique characteristics of the queue. Algorithm: 1. Algorithm for Inserting an item in a circular queue. CQINSERT (maxsize, item) Let cqueue[maxsize] is an array for implementing a queue. 1. Initialize front = -1 and rear = -1 2. Check, if rear = maxsize -1 then set rear = 0 else set rear = rear + 1 3. Check, if rear = front then print : “Circular queue overflow” Also check, if rear = 0 then set rear = maxsize – 1 else set rear = rear -1 and return. 4. Set cqueue[rear] = item 5. Check, if front = -1 then set front = 0 6. Return 2. Algorithm for Deleting an item from a circular queue. CQDELETE (maxsize) 1. Check, if front = -1 then print : “Circular queue underflow” and return 2. Set item = cqueue[front] 3. Check, if front = rear then set front = -1 and rear = -1 else check, if front = maxsize – 1 then set front = 0 else set front = front + 1 4. Return the deleted element from circular queue. Conclusion: Thus we can implement circular queue by visualizing the onedimensional array as circular. The circular queue overcomes the problems associated when deletion is made from the front. And another one is that even if the queue in reality is empty, the normal queues give full condition. Experiment No. 5 Aim: Implementation of DOUBLE ENDED Queue menu driven program Theory: A double-ended queue(dequeue, often abbreviated to deque, pronounced deck) is a linear list in which elements can be added or removed at either end but not in the middle. The items can be added or deleted from the front or rear end, but no changes can be made elsewhere in the list. There are 2 types of Double Ended Queue 1. Input Restricted Deque 2. Output Restricted Deque - Input Restricted Deque An input-restricted deque is one where deletion can be made from both ends, but insertion can be made at one end only. - Output Restricted Deque An output-restricted deque is one where insertion can be made at both ends, but deletion can be made from one end only. The two possibilities that must be considered while inserting or deleting elements into the queue are When an attempt is made to insert an element into a deque which is already full, an overflow occurs. When an attempt is made to delete an element from a deque which is empty, underflow occurs. Representation of Deque The operations that can be performed on deques are: 1. Insert an item from front end 2. Insert an item from rear end 3. Delete an item from front end 4. Delete an item from rear end Algorithm: 1. Algorithm for Inserting an item at Rear end of the Double Ended Queue Let MAXSIZE be the maximum number of elements in queue. DQ [] is array. 1. If (front==0&&rear= = MAXSIZE-1)||(front==rear+1) then print queue is full and return Else accept the value 2. if(rear== -1&&front== -1) a. Set rear = 0 b. Set front=0 3. if(rear==max-1) set rear=0 else set rear=rear+1 4. Set DQ [rear] = value 2. Algorithm for Deleting an item from front end of the Double Ended Queue 1. If (front= = -1||rear== -1) then print queue is empty and return Else Set Item=DQ [front] 2. if(front==rear) a. Set rear = -1 b. Set front= -1 3. if(front==max-1) set front=0 Else Set front=front+1 3. Algorithm for Inserting an item at front end of the Double Ended Queue 1 if (front==0&&rear= = MAXSIZE-1)||(front==rear+1) then print queue is full and return Else accept the value 2.if(rear== -1&&front== -1) a Set rear = 0 b Set front=0 3 if(front==0) set front=max-1 else set front=front-1 4. Set DQ [front] = value 4. Algorithm for Deleting an item from a rear end of Double Ended Queue 1. If (front= = -1||rear==-1) then print queue is empty and return Else Set . Item=DQ [rear] 2. if(front==rear) a Set rear = -1 b Set front= -1 3. if(rear==0) set rear=max-1 Else Set rear=rear-1 Conclusion: Thus we can insert and delete data at both (rear and front) ends by using double ended queue data structure. Experiment No. 6 Aim: Implementation of SINGLY LINKED LIST Theory: Linked lists are special lists of some data elements linked to one another. The logical ordering is represented by having each element pointing to the next element. Each element is called a node, which has two parts: INFO part which stores the information and POINTER which points to the next element. A singly linked list is a dynamic structure. It may grow or shrink. Growing or shrinking depends on the operation made. In Singly linked list we have one pointer (next) pointing to the next node. Algorithm: 1. Inserting a node at the beginning 1. Check if ptr = NULL then print : “overflow” and return else create a new node from memory and assign its address to ptr 2. Set ptr.info = item 3. Set ptr.next = start 4. Set start = ptr 5. Return 2. Inserting a node at the end 1. Check if ptr = NULL then print : “overflow” and return else create a new node from memory and assign its address to ptr 2. Set ptr.info = item 3. Set ptr.next = NULL 4. Check if start = NULL then set start = p 5. Set loc = start 6. Repeat step 7 until loc.next != NULL 7. Set loc = loc.next 8. Set loc.next = p 9. Return 3. Inserting a new node at specified position 1. Check if ptr = NULL then print : “overflow” and return else create a new node from memory and assign its address to ptr 2. Set ptr.info = item 3. Check if start = NULL then set start = p and set p.next = NULL 4. Set temp = start and i = 0 5. Repeat step 6 and 7 until i<loc 6. Set temp = temp.next 7. Set i = i +1 8. Set p.next = temp.next 9. Set temp.next = p 10. Return. 4. Deleting first node . 1. Check, if start = NULL then print: “Linked list is empty” and return 2. Set ptr = start 3. Set start = start.next 4. Print the deleted item 5. Return 5. Deleting last node 1. Check, if start = NULL then print: “Linked list is empty” and return 2. if start -> next = NULL then 2.1. Set ptr = start 2.2. Set start = NULL 2.3. print, element deleted i.e., ptr.info 3. Set ptr = start 4. Repeat steps 5 to 6 till ptr.next != NULL 5. Set loc = ptr 6. Set ptr = ptr.next 7. Set loc.next = NULL 6. Deleting the node from specified position 1. Check if ptr = NULL then print: “Linked list is empty” and return 2. Set i = 0 and set ptr = start 3. Repeat step 4 to 9 until i<=loc 4. Set temp = ptr 5. Set ptr = ptr.next 6. Set i = i +1 7. Print element deleted 8. Set temp.next = ptr.next 9. Return Conclusion: Thus we can easily perform insertion and deletion of nodes. Also accessibility of a node in the forward direction is easier. Limitations of linked list are: Accessing the preceding node of a current node is not possible as there is no backward traversal. Experiment No. 7 Aim: Implementation of different operations CONCATENATE, SPLIT, REVERSE, COUNT on linked list: COPY, Theory: Linked lists are special lists of data elements linked to one another. It is a general list and each element in the is called a node, which has two parts: INFO part which stores the information and POINTER which points to the next element. The following are the operations performed in the singly linked list Copy from one list to another Concatenation of two lists Split one list into two Reverse the list Count the No of nodes in the list Algorithm: 1) Copying from one list to other 1) Set start at the start of the original list 2) Set a temporary pointer ptr to point to the original list 3) Set a pointer t as t= NULL 4) Repeat step 5 to step 9 until ptr->link!=NULL 5) Allocate memory for a new node temp 6) Copy ptr->data to temp->data 7) Set temp->link to t 8) Set ptr as ptr->link 9) Set t as t=temp 2) Concatenation of two lists 1) Set start at the start of the First list 2) Set a second pointer second to the start of the Second list 3) Repeat step4 until start->link!=NULL 4) Set start as start=start->link 5) Set start->link to second pointer 3) Split one list into two 1) Set start at the start of the original list 2) Set a variable p as p=1 and pos as position where to split 3) Repeat step4 to step 6 until start->link!=NULL 4) Set start as start->link 5) Increment p 6) Check if p=pos then a) Set another pointer st as start->link b) set start->link as NULL Reverse the list 1) Set start at the start of the original list 2) Set three pointers p1,p2 and p3 3) Set p1 as p1=start; 4) Set p1->link as NULL 5) Set p2 as start->link 6) Set p2->link as p1 7) Repeat step8 to step11 until start!=NULL 8) Set p3 as start->link 9) Set p3->link as p2 10) Set p2=p3 11) Set start as start->link 12) Set a new pointer rev as rev=p2 to point to the start of the reversed list 4) Count the no. of nodes in a list 1) Set start at the start of the original list 2) Set a variable count as count=0 3) Repeat step4 to step5 until start->link!=NULL 4) Set start as start->link 5) Increment count Conclusion: Linked list makes operations such as reverse, concatenate, copy, split etc to be implemented in an easier way. Experiment No. 8 Aim: Implementation of BINARY TREE CREATION AND TRAVERSAL Theory: A tree is a non-linear data structure in which items are arranged in a sorted sequence. It is used to represent hierarchical relationship existing among several data items. A binary tree is a tree data structure in which each node has at most two children. Typically the child nodes are called left and right. Definitions for rooted trees A directed edge refers to the link from the parent to the child (the arrows in the picture of the tree). The root node of a tree is the node with no parents. There is at most one root node in a rooted tree. A leaf is a node that has no children. The depth of a node n is the length of the path from the root to the node. The set of all nodes at a given depth is sometimes called a level of the tree. The root node is at depth zero. The height of a tree is the length of the path from the root node to its furthest leaf. A tree with only a root node has a height of zero. Siblings are nodes that share the same parent node. If a path exists from node p to node q, where node p is closer to the root node than q, then p is an ancestor of q and q is a descendant of p. The size of a node is the number of descendants it has including itself. Often, one wishes to visit each of the nodes in a tree and examine the value there. There are several common orders in which the nodes can be visited, and each has useful properties that are exploited in algorithms based on binary trees. Pre-order, in-order, and post-order traversal visit each node in a tree by recursively visiting each node in the left and right subtrees of the root. If the root node is visited before its subtrees, this is preorder; if after, postorder; if between, in-order. Algorithm: 1. Create_tree (info, node) where info is information for which we have to create node and node structure type variable and pointer to both left and right child. 1. Check whether tree is empty if node = NULL then create node and set left_child[node] = NULL and set right_child[node] = NULL 2. If info[node] >= info left_child[node] = call create_tree(info, left_child[node]) Else right_child[node] = call create_tree(info, right_child[node]) 3. Return (node) 2. Inorder Traversal: In inorder traversal, the left subtree is traversed recursively in inorder before visiting the root node. After visiting the root node, the right subtree is taken up and it is traversed recursively in inorder. 1. Traverse left subtree in inorder(L) 2. Visit the root node (N) 3. Traverse the right subtree in inorder(R) 3. Preorder Traversal: In preorder traversal, the root node is visited before traversing left and right subtrees. The preorder notion is recursive in nature, so even within the left subtree and right subtree the following three steps are followed. 1. Visit the root node(N) 2. Traverse the left subtree in preorder(L) 3. Traverse the right subtree in preorder(R). 4. Postorder Traversal: In a postorder traversal the left and right subtree are recursively processed before visiting the root. The left subtree is taken up first and is traversed in postorder. Then the right subtree is taken up and is traversed in postorder. Finally, the data of the root node is displayed. 1. Traverse the left subtree in postorder(L) 2. Traverse the right subtree in postorder(R) 3. Visit the root node(N). Conclusion: Thus binary tree is a finite set of data items which is either empty or consists of a single item called the root and two disjoint binary trees called left subtree and right subtree. A binary tree can be traversed in inorder, preorder and postorder. Experiment No. 9 Aim: Implementation of CONSTRUCTION of EXPRESSION TREE using POSTFIX EXPRESSION. Theory: An expression tree for an arithmetic, relational, or logical expression is a binary tree in which: The parentheses in the expression do not appear. The leaves are the variables or constants in the expression. The non-leaf nodes are the operators in the expression: A node for a binary operator has two non-empty subtrees. A node for a unary operator has one non-empty subtree. The operators, constants, and variables are arranged in such a way that an inorder traversal of the tree produces the original expression without parentheses. Example: Create expression tree for the following infix expression 3+(4*5-(9+6)) Steps for creating expression tree using postfix expression: Postfix Expression: Step 1: + Step 2: / Step 3: 8 2, 6, *, 3, 8, /, + Step 4: 3 Step 5: * Step 6: 6 Step 7: 2 Postfix to Expression Tree Algorithm: 1 Scan the postfix expression from left to right 2. If current element is an operand 2.1 Create a node for it( temp) 2.2 set temp->data as operand 2.3 set temp->left=NULL 2.4 Set temp->right=NULL 2.5 Push the node(temp) to stack 3.If element is an operator 3.1 Create a node for it( temp) 3.2 pop top element and assign to a 3.3 Pop next element and assign to b 3.4 Assign temp->data as operator 3.5 Set temp->left as a 3.6 Set temp->right as b 3.7 push temp 4.pop the top element from stack and assign it as root 5 if (root!=NULL) 5.1repeat step 5 for root->left 5.2Print root->data 5.3repeat step 5 for root->right Conclusion: Expression trees impose a hierarchy on the operations in the expression. Terms deeper in the tree get evaluated first. This allows the establishment of the correct precedence of operations without using parentheses. Experiment No. 10 Aim: Implementation of BINARY SEARCH TREE (BST) program Theory: A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and: 1. All keys in the left subtree (if there is one) are less than the key in the root node. 2. All keys in the right subtree (if there is one) are greater than (or equal to) the key in the root node. 3. The left and right subtrees of the root are binary search trees. Insertion: Inserting an item with key 13 into a binary search tree. Lightly shaded nodes indicate the path from the root down to the position where the item is inserted. The dashed line indicates the link in the tree that is added to insert the item. Deletion: Deleting a node z from a binary search tree. In each case, the node actually removed is lightly shaded. (a) If z has no children, we just remove it. (b) If z has only one child, we splice out z. (c) If z has two children, we splice out its successor y, which has at most one child, and then replace the contents of z with the contents of y. Algorithm Insertion: To insert a new value v into a binary search tree T. The procedure is passed a node z for which key[z] = v, left[z] = NIL, and right[z] = NIL. It modifies T and some of the fields of z in such a way that z is inserted into an appropriate position in the tree. 1. y NIL 2. x 3. while x 4. do y 5. root[T] NIL x if key[z] < key[x] 6. then x left[x] 7. else x right[x] 8. p[z] y 9. if y = NIL 10. then root[T] z 11. else if key[z] < key[y] 12. 13. then left[y] z else right[y] z TREE-INSERT begins at the root of the tree and traces a path downward. The pointer x traces the path, and the pointer y is maintained as the parent of x. After initialization, the while loop in lines 3-7 causes these two pointers to move down the tree, going left or right depending on the comparison of key[z] with key[x], until x is set to NIL. This NIL occupies the position where we wish to place the input item z. Lines 8-13 set the pointers that cause z to be inserted. Deletion: The procedure for deleting a given node z from a binary search tree takes as an argument a pointer to z. If z has no children, we modify its parent p[z] to replace z with NIL as its child. If the node has only a single child, we "splice out" z by making a new link between its child and its parent. Finally, if the node has two children, we splice out z's successor y, which has no left child and replace the contents of z with the contents of y. TREE-DELETE(T, z) 1. if left[z] = NIL or right[z] = NIL 2. then y 3. else y 4. z TREE-SUCCESSOR(z) if left[y] NIL 5. then x left[y] 6. else x right[y] 7. if x NIL 8. then p[x] p[y] 9. if p[y] = NIL 10. then root[T] 11. else if y = left[p[y]] 12. then left[p[y]] 13. else right[p[y]] 14. if y 15. x x z then key[z] 16. 17. x key[y] If y has other fields, copy them, too. return y TREE SUCCESSOR(x) 1. if right[x] 2. NIL then return TREE-MINIMUM(right[x]) 3. y 4. while y 5. do x y 6. y p[y] 7. p[x] NIL and x = right[y] return y TREE-MINIMUM (x) 1. while left[x] 2. do x 3. return x NIL left[x] In lines 1-3, the algorithm determines a node y to splice out. The node y is either the input node z (if z has at most 1 child) or the successor of z (if z has two children). Then, in lines 4-6, x is set to the non-NIL child of y, or to NIL if y has no children. The node yis spliced out in lines 7-13 by modifying pointers in p[y] and x. Splicing out y is somewhat complicated by the need for proper handling of the boundary conditions, which occur when x = NIL or when y is the root. Finally, in lines 14-16, if the successor of z was the node spliced out, the contents of z are moved from y to z, overwriting the previous contents. The node y is returned in line 17 so that the calling procedure can recycle it via the free list. Conclusion: The keys in a binary search tree are always stored in such a way as to satisfy the binary-search-tree property: The binary-search-tree property allows us to print out all the keys in a binary search tree in sorted order by a simple recursive algorithm, called an inorder tree walk. The algorithm derives its name from the fact that the key of the root of a subtree is printed between the values in its left subtree and those in its right subtree. Experiment No. 11 Aim: Implementation of INSERTION SORT, RADIX SORT and SHELL SORT menu driven program Theory: Insertion sort: If the first few objects are already sorted, an unsorted object can be inserted in the sorted set in proper place. This is called insertion sort. An algorithm consider the elements one at a time, inserting each in its suitable place among those already considered (keeping them sorted). Insertion sort is an example of an incremental algorithm; it builds the sorted sequence one number at a time. This is perhaps the simplest example of the incremental insertion technique, where we build up a complicated structure on n items by first building it on n − 1 items and then making the necessary changes to fix things in adding the last item. The given sequences are typically stored in arrays. Example: Following figure shows the operation of INSERTION-SORT on the array A= (5, 2, 4, 6, 1, 3). Each part shows what happens for a particular iteration with the value of j indicated. j indexes the "current card" being inserted into the hand. Elements to the left of A[j] that are greater than A[j] move one position to the right, and A[j] moves into the evacuated position. Radix sort: It is a small method that many people intuitively use when alphabetizing a large list of names. (Here Radix is 26, 26 letters of alphabet). Specifically, the list of names is first sorted according to the first letter of each names, that is, the names are arranged in 26 classes. Intuitively, one might want to sort numbers on their most significant digit. But Radix sort do counter-intuitively by sorting on the least significant digits first. On the first pass entire numbers sort on the least significant digit and combine in a array. Then on the second pass, the entire numbers are sorted again on the second leastsignificant digits and combine in a array and so on. Following example shows how Radix sort operates on seven 3-digits number. In the above example, the first column is the input. The remaining shows the list after successive sorts on increasingly significant digits position. The code for Radix sort assumes that each element in the n-element array A has d digits, where digit 1 is the lowest-order digit and d is the highest-order digit. Shell Sort: Shell sort, also known as Shell sort or Shell's method, is an in-place comparison sort. It generalizes an exchanging sort, such as insertion or bubbles sort, by starting the comparison and exchange of elements with elements that are far apart before finishing with neighboring elements. Starting with far apart elements can move some out-ofplace elements into position faster than a simple nearest neighbor exchange. The running time of Shell sort is heavily dependent on the gap sequence it uses. An example run of Shell sort with gaps 5, 3 and 1 is shown below. Algorithm: Insertion Sort 1. Start. 2. Start the loop from 2nd position of array and repeat process from step 3 till size of an array is reached till maximum. 3. Assign the value of ith location of array into temp variable. 4. Start the 2nd loop from i-1 till1 and repeat the step 5 till j is equal to 1 5. Check whether the value of array of „I‟ is less than value of array of i-1, if yes swap the values. 6. Stop the loop. Algorithm: Shell Sort Let a [maxsize] be no. of elements in array. 1. Initialize increment=3,set i=0 2. Repeat steps 3 to 10 until increment>0 3. Repeat steps 4 to 9 until i<maxsize 4. Set j=1 5. Set temp=a[i] 6. Repeat steps 7 and 8 until j>=increment and a [j-increment>temp] 7. Set a[j]=a[j]-increment 8. Set j=j-increment 9. Set a[j]=temp 10. If increment/2 !=0 then set increment=increment/2 Else if increment==1 then set increment=0 Else set increment=1 Algorithm: Radix Sort 1. Start. 2. Let x be an array of 10 i.e. bucket[0 to 9]. 3. Let m be the number of digits. 4. Start with for loop with digit=1 and continue step 4 till digit<=m 4.1 Initialize all elements of bucket to NULL; 4.2 Divisor = 1; 4.3 for(k = 1; k <= digit; k++) divisor = 1; 4.4 for(i = 0; i < n; i++) d = (x[i]/divisor)%10; 4.5 insert x into bucket[d] 4.6 for(i = 0; i<10; i++) if(bucket[i]!= NULL) Insert entries from bucket[i] into the array x. 5. Stop. Conclusion: Insertion sort is an elementary sorting algorithm. Insertion sort is well suited for sorting small data sets or for the insertion of new elements into a sorted sequence. Shell sort improves on the efficiency of insertion sort by quickly shifting values to their destination. Radix sort allows processing of the entire file without subdividing files and keeping track of where each sub-file begins and ends. Experiment No. 12 Aim: Implementation of INDEX SEQUENTIAL, INTERPOLATION SEARCH menu driven program Theory: Indexed Sequential Searching Indexed sequential search is a technique used to search an element in a given list. In indexed sequential search technique, it is necessary to have the elements to be arranged in the ascending order in a list. In indexed sequential search, an auxiliary table is set aside along with the list in which the key element is to be searched. This auxiliary table is called Index. The Index contains two columns, kindex and pindex. Column kindex contains elements from the given list. Column pindex contains address of the memory location where the elements of the given list represented by kindex are stored. Indexed sequential search can be explained with the help of following example: Suppose you have to find the key element 289 in the given list of 18 elements. Let us take an index table that contains 3 records. Therefore, the given list is divided into three parts each having 6 (calculated as 18/3 = 6) elements and each record in the Index represents the 6th element in the given list. The key element 289 is smaller than the first element 342 in the kindex. Therefore, you do not need to search the entire list. You can simply search for the key element in the sub list x [0..6] Interpolation Search: The Interpolation search algorithm works on a mathematically calculated best guess approach to array searching. The algorithm uses the lowest and highest values in the array and the number of elements to calculate the most likely location of the result. If the most likely location is not the correct location, the algorithm uses it as either the new lowest or highest value, depending if it is lower or higher than the search value and calculates the most likely location again. The algorithm repeats the calculation until it finds the answer, or until the visits the same location twice. If a location is visited twice, the value does not exist Example: Search for the key 20 in the following array using interpolation search: int[] a = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30} middle = low + ( high - low )*( (key – a[low]) / ( a[high] – a[low] )) middle = 0 + ceil(15 – 0)* ( (20 – 0) / (30 – 0) ) = 0 +10 =10 a[middle] = 20 which is equal to key. So key found at index 10. Algorithm for Indexed Sequential Search: 1. i=0 2. while (i< indexsize and kindex [i]< k) i=i+1 end_while 3. if i=0 then lowlim = 0 else lowlim = pindex [i-1] end_if 4. if i=indexsize then hilim=n-1 else hilim=pindex [i]-1 end_if 5. j=lowlim 6. While (j<= hilim and A [j] ! = k) j=j+1 end_while 7. if j> hilim then return -1 else return j end_if Algorithm for Interpolation Search : 1. i := 1 2. j := n 3. LO := ai 4. HI := aj 5. if x < LO then return 0 6. if x ≥ HI then i := j loop invariant: x ≥ LO and x < HI 7. while (i<j) do m := floor( i + (j-i)*(x-LO) / (HI-LO) ) loop invariant: m ≥ i and m <: j MID := am+1 if (x < MID) then j := m HI := MID else i := m+1 LO := MID 8. if (x ≠ ai) then i := 0 return i Conclusion: In indexed sequential searching technique, first of all an index file is created that contains references to a group of records, once an index is obtained, the partial searching takes less time since it is to be located in the group/bucket specified by the index. In interpolation search is a modified algorithm of Binary search reducing the complexity. It uses the lowest and highest values in the array and the number of elements to calculate the most likely location of the result. Experiment No. 13A Aim: Implementation of BREADTH FIRST SEARCH algorithm. Theory: This is the method, instead of going deep into the graph, we examine the nodes across the breadth of a tree, before going to the next level. Unlike DFS ,where we visit the node then push it on to the top of the stack. The next node should be unvisited one, if no such node exists we backtrack the most LRU node. In BFS we use queue. In this method, we pick a node to visit first and place it‟s unprocessed adjacent nodes in queue. Repeatedly, take a node from the front of a queue. If this node is unvisited, then we visit the node and then place all it‟s neighbors in the queue. 1 2 3 5 4 6 7 9 8 BFS : 1 2 3 4 5 6 7 8 9 Algorithm: 1. Select any node in the graph. Mark this node as visited. 2. Find the adjacent node, add them to the queue. 3. Visit this node, which is at the front of the queue. Delete this node form queue and place it‟s adjacent in node in queue. (We can use adjacency matrix for it). Make this new node as visited. 4. Repeat step 2 and 3 till queue becomes empty. 5. Stop. Conclusion: In this way, we have studied breadth wise graph traversal technique which uses queue for implementation. Experiment No. 13B Aim: Implementation of DEPTH FIRST SEARCH algorithm. Theory: This is the method of visiting all nodes, by traversing all nodes as deeply as possible. When there are no adjacent, non-visited nodes, then we proceed backwards (backtrack), and we repeat the process, by maintaining the stack to keep track of visited nodes, so that this can help in backtracking. 1 2 3 5 4 6 7 9 8 DFS : 1 2 4 6 9 7 5 8 3 Algorithm: 1. Select any node in the graph. Mark this node as visited, push this node on the stack. 2. Find the adjacent node to the node on top of stack, and which, and which is not yet visited. (We can use adjacency matrix for it). Make this new node as visited and push onto the stack. 3. Repeat step 2, until no new adjacent node to the top of the stack, node can be found. When no new adjacent node can be found, pop the top of the stack. 4. Repeat step 2 and 3 till stack becomes empty. 5. Repeat above steps, if there are any more nodes which are still unvisited. Conclusion: In this way, we have studied depth wise graph traversal technique which uses stack for implementation.