Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
1a) Describe the characrteristics of a complete binary tree. -A complete binary tree is a binary tree in which all levels are filled to the max (ie. all possibles positions are filled) except possiblely the lowest, and on this level all nodes come from the left up to a point (ie all internal nodes on the level above are to the left of any external nodes). b)What is an extended binary tree? -An extended binary tree is a binary tree, which has null leaves inserted for purposes of analysis. Eg a complete binary tree may be extended to make it full. (Formed from Mr. Pemberton's answer) C) What is the relationship between the number of empty leaves in an extended binary tree, (symbolized by squares) and the number of internal nodes (symbolized by circles)? -The number of null nodes in an extended binary tree is one greater than the total nubmer of internal nodes. Proof - Number of internal h-1 nodes = Σ 2^L and number external nodes = 2 ^ H. Therefore when L=0 the number of external nodes is 1 greater than the number of internal nodes. D) How many nodes are their in a complete binary tree with levels 0 to N, in which level 'N' is completely filled with leaves in all possible positions? -The number of nodes on a full level is found by 2 to the power of L where L is the level. Therefore, sum all the levels from 0 to N to get your answer. Therefore, L = 0 below the sigma and n above and 2 to the n power of L on the right as the equation to be summed. (ie Σ 2^L) L=0 2a) Define the term heap. - A heap is a special type of binary tree in which all the nodes are either greater (in the case of a max heap) in key value than its children or less than its children (in the case of a min heap). B) C)Write an algorithm to Re-heapify a heap if an item is arbitrarily removed from a node. procedure BubbleUp(Inx : integer) ParentInx <-- (Inx) div 2 while (Inx > 0) and (Array[Inx] > Array[ParentInx]) Exchange Array[Inx]<---->Array[ParentInx] Inx<--ParentInx ParentInx <-- (Inx) div 2 procedure TrickleDown(A, Inx) LChildInx ← Inx * 2 RChildInx ← Inx * 2 + 1 if LChildInx<= hep-size[A] and A[LChildInx] > A[Inx] then largest ← LChildInx else largest ← Inx if RChildInx <= heap-size[A] and A[RChildInx] > A[Largest] then exchange A[Inx] ←→ A[Largest] TrickleDown( A, largest) ► Calls itself recusivly D) For the implementation of priority queue "Q" using heaps write the follwing. I. Initialize(Q) 1 heap-size[Q] ← lenght[A] 2 for i ← Floor(Lenght[A]/2) downto 1 3 do MAX-HEAPIFY(A, i) II Insert(Q) 1 heap-size[A] ← heap-size[A] + 1 2 A[heap-size[A]] ← - ∞ 3 HEAP-INCREASE-KEY( A, heap-size[A], key) III Remove(Q) 1 if heap-size[A] < 1 2 then error "heap underflow" 3 max ← A[1] 4 A[1] ← A[heap-size[A]] 5 heap-size[A] ← heap-size[A] - 1 6 MAX-HEAPIFY(A ,1) 7 return max 3) Define the following operations on a dynamic stack “S” where k is the key value of the element and x is the pointer to the element. A) Search (S,k) A query that, given a set S and a key value k, returns a pointer x to an element in S such that key[X]=k, or nil if no such element belongs to S. B) Insert(S,x) A modifying operation that augments the set S with the element pointed by x C) Delete(S,x) A modifying operation that, given a point x to an element in the set S, removes x from S D) Minimum(S) A query on a totally ordered set S that returns a pointer to the element of S with the Smallest key E) Maximum(S) A query on a tatally ordered set S that returns a pointer to the element of S with the largest key. F) Successor(S,x) A query that, given an element x whose key is from a totally ordered set S, returns a pointer to the next larger element in S, or nil if x is the maximum element. G) Predecessor(S,x) A query that, given an element x whose key is from a totally ordered set S, returns a pointer to the next smaller element in S, or nil if x is the minimum element. H) 4a). Name the Insert and Delete operation of a queue - The insert on a queue is called Enqueue and the delete is called Dequeue. B) Implement the algorithm to insert an item into the queue and comment. - ENQUEUE(Q, x) 1 if head[Q] = tail[Q] mod Length[Q] + 1 2 then error "Queue overflow" 3 ► mod function used instead of + 1 as head may be at 1 4 else Q[tail[Q]] ← x 5 ► Insertion in queues is only done at the tail (part of the ADT) 6 tail[Q] ← tail[Q] mod length[Q] + 1 7 return x C) Implement the algorithm to delete an item from the queue and comment. DEQUEUE(Q) 1 if head[Q] = tail[Q] 2 then error "Queue Underflow" 3 else x ← Q[head[Q]] 4 head[Q] ← head[Q] mod Length[Q] + 1 5 return x D) Explain how to implement two stacks into one array A[1...n] in such a way that neither stack overflows unless the total number of elements in both stacks together is n. [Note: The Insert and Delete Operations should run in O(1) time] How this would be achieved is by setting the array bases at opposite ends of the array. The one which is based on the left would grow rightward and the other leftward (→ ←). The insert/push and delete/pop well have to be designed for each so that it moves relative to its stack. 5a) Define the characteristics of the Abstract Data Type List Structure. - A linked list is of linear structure. It links its elements called nodes using pointers to the next and previous node or one of the two, but atleast one of them. It should support a search, insert, and delete. B)Describe using pseudocode Algorithm, implementation of the methods insertBefore(p, e), insertFirst(e), and insertlast(e) of the list, ADT, assuming that the list is implemented using double linked list. - InsertBefore takes p, a pointer to the element, e the element to insert. Inserts e before p. InsertBefore(L, p, e) 1 if p = nil 2 then error "Element to insert before dosn't exist" 3 else if head[L] = p 4 5 6 7 8 9 then head[L] ← e prev[e] ← prev[p] prev[p] ← e if prev[e] <> nil then next[prev[e]] ← e next[e] ← p - InsertFirst(L, e) 1 next[e] ← head[L] 2 if head[L] <> nil 3 then prev[head[L]] ← e 4 head[L] ← e 5 prev[e] ← NIL - insertLast(L, e) 1 x ← head[L] 2 y← x 3 while x <> nil 4 do y ← x 5 x ← next[x] 6 prev[e] ← y 7 if head[L] <> nil 8 then next[y] ← e 9 else head[L] ← e 10 next[e] ← nil 6a)For an array A[i] or length n, implement the insertion sort algorithm using pseudo code. - INSERTION-SORT(A) 1 for j ← 2 to length[A] 2 do key ← A[j] 3 ► Insert A[j] into the sorted sequence A[1..j-1] 4 I←j–1 5 While I 0 and A[I] key 6 Do A[I + 1] ← A[I] 7 I←I–1 8 A[I + 1] ← key B) for the algorithm above show that the worst case running time for the T(n) is of the form an2 + bn + c - Worst case cost: reverse ordered numbers tj=j, so j=2n tj = j=2n j =n(n+1)/2-1, and j=2n(tj -1) = j=2n(j -1) = n(n-1)/2, and T(n) = c1n + c2(n-1) + c4(n-1) + c5(n(n+1)/2 -1) + + c6(n(n-1)/2 -1) + c7(n(n-1)/2)+ c8(n-1) =((c5 + c6 + c7)/2)n2 +(c1 + c2 + c4 +c5/2-c6/2-c7/2+c8)n-(c2 + c4 + c5 + c8) =an2+bn+c C) Describe the assumptions made in arriving at the conclusion that for above situation the growth function is O(n2). - Order of growth Lower order item(s) are ignored, just keep the highest order item. The constant coefficient(s) are ignored. The rate of growth, or the order of growth, possesses the highest significance. Use (n2) to represent the worst case running time for insertion sort. Typical order of growth: (1), (lg n), ( n), (n), (nlg n), (n2), (n3), (2n), (n!) Asymptotic notations: , O, , o, . Loop invariant At the start of each iteration of the for loop, the subarray A[1..j-1] contains original A[1..j-1] but in sorted order. Proof: Initialization : j=2, A[1..j-1]=A[1..1]=A[1], sorted. Maintenance: each iteration maintains loop invariant. Termination: j=n+1, so A[1..j-1]=A[1..n] in sorted order. 7a) Define the Vector Abastract Data Tupe S storing n elements, in terms of the operations that can be performed on it. Indicate for each of the methods what actions they perform and what their parameters mean. ElematRank( r): Returns the element of S with rank r; an error condition occurs if r<0 or r>n-1. ReplaceAtRank(r, e): Replace with e the element at rank r and returns the element replaced; an error condition occurs if r<0 or r>n-1. RemoveAtRank( r): Removes and returns from S the element at Rank r; an error condition occurs if r<0 or r>n-1 InsertAtRank(r, e): Inserts a new element, e, into S to have a rank r; an error condition occurs if r<0 or r>n. b. Implement pseudo code the methods identified above. ElementAtRank(S, r) 1 return S[r] ReplaceAtRank(S, r, e) 1 x ← S[r] 2 S[r] ← e 3 return x RemoveAtRank(S, r) 1 e ← S[r] ►e is a temporary variable 2 For i ← r to n-2 3 do A[i]←A[i+1] ►fill in for the reoved element 4 size[S] ← size[S] - 1 5 return e InsertAtRank(S, r, e) 1 for i ← n-1downto r do 2 S[i+1] ← S[i] ►make room for new element 3 S[r] ← e 4 size[S] ← size[S] + 1 10. Q. Give a pseudo-code description of the in place version of quick sort that is specialized to take an array as input and returns the same array as output. A. QuickSort(A, p, r) 1 if p < r 2 then q ← Partition(A, q, r) 3 QuickSort(A, p, q -1) 4 QucickSort(A, q + 1, r) Partition(A, p, r) 1 x ← A[r] 2i←p-1 3 for j ← p to r -1 4 do if A[j] = x 5 then i ← i + 1 6 exchange A[i] ←→A[j] 7 exchange A[i+1] ←→ A[r] 8 return i + 1 11 Q. Let A be a collection of Objects. Describe an efficient method for converting A to a set. That is remove all duplicates from the collection. A. Simply define an additional storage location such as an array and copy all the objects to it checking to see that they do not already exist before copying there by removing duplicates. Do u have another way? 12. For each of the following statements about re-black trees, determine wheter it is true or false, if you think it is true, provide justification. If you think it is false, give a counter example. Background info -A re-black tree is a binary search tree with one extra bit of storage per node: its color, which can either be RED or BLACK. By constraing the way nodes can be colored on a ny path from the root to a leaf, red-black trees ensure that no such path is more than twich as long as any other, so that the tree is approximately balanced. Each node of the tree now contains the fields color, key, left, right, and p. Property of a binary search tree: - Let x be a node in a binary search tree. if y is a node in the left subtree of x, then key[y] <= key[x]. If y is a node in the right sub tree of x, then key[x] <= key[y]. Propertys of a red-black tree (in addtion): 1 - Every node is either red or black 2 - The root is black 3 - Every leaf (NIL) is black 4 - If a node is red, then both is children are black 5 - For each node, all paths from the node to descendant leaves contain the same number of black nodes. a. Q. A sub-tree of a red-black tree is its-self a red black tree. A. Not nessarily becase if that sub-tree is rooted at a red node then it is not a red black tree due to violation of rule 2. b. Q. The sibling of an external node (NIL) is either an external node or it is red. A. Yes this one holds don't have the time to go through it draw a couple trees test it out (Note: a sibling is not any node on your level but the other child of your parent. c. Q. Given a red black tree T, there is a unique(2, 4) treeT' associated with T. A. Yes this holds as to form the (2, 4) tree all we would have to do is "merge" all red children with their parent there by bring all external nodes to the same level as each external node had to have already had the same black depth, so now they meet the property of (2, 4) trees all external nodes haveing the same depth. d. Q. Given a (2, 4) tree T, there is a unique red-black tree associated with T. A. Not sure but i doubth this holds. 14) When trying to simulate pointers and/or records in languages that do not support them there are two basic methods used, “array indexes” and “mathematical relationships”. The first, “array indexes”, is based on using integer references in lieu of traditional pointers that point to memory addresses. Let us say for example we wish to implement a linked list in a language that doesn’t support pointers, if it were a singly linked list, we could use two arrays, one to store the key values and one to store the index of the next node in the data structure. We could establish a “link” between the arrays by using the index of the array, so that each key value in the “Key array” would have the same index as its next pointer in the “Next array”. (See figure 1) Figure 1 Index 1 Key_array 5 Next_array -1 2 3 4 * 3 4 5 7 1 (NB: * indicates head of list) Figure 2 Index 1 List_array 5 2 -1 3 3 4 4 5 6 7 7 8 1 9 10 The head of the list is at index 2. The key value is 3 and the next array reference is 4. The key at index 4 is 7 and the “next array” is 1, which indicates that the next node is at index 1. At index 1 we see the next pointer is -1 which is used as a null pointer indicating the end of the list (used as it is not possible to have an index of -1). A single array can also be used with an offset system to differentiate between key and reference. However, there is a limitation as arrays are homogenous and can only store one data type at a time forcing both the key and reference to be of the same type (see figure 2). To simulate records we could simply use multiple arrays, each of the arrays representing a different record field. For example, we could say that to represent the following record definition we could use the group of arrays in Figure 3. (NB: the example assumes that storing of 4 or less records is needed). RPerson = record First_Name: String; Last_Name: String; DOB: Date; End; First_Name: Array[1..4] of String; Last_Name: Array[1..4] or String; DOB: Array[1..4] of Date; Visual display of arrays (Figure 2) Index 1 First_Name 2 3 4 Last_Name DOB The second method that is used is “mathematical relationships”. Very commonly, this is used in the implementation of the tree data structures. These relationships are fairly simple but fail to cope with unbounded trees as a the number of children per node is not definite thus causing relationships to be impossible or extremely difficult to establish. For instance let’s take a binary tree stored in a array. The root of the tree would be at the first index of the array, which would be one are the relation ships don’t hold for 0 based arrays. Its left child would be relative to it as would be it’s left child’s left child and so on, the same holds for the right children. The relationships are simple and are based on the index of the node in the array. In the following relationships “i” is the index of the node. To find: the parent you get the floor of i/2, the left child 2i and right child 2i + 1. Here is an example of pseudo code to search the linked list shown in figure 1. List-Search (k) X Head[Next_Array] While x <> -1 Do x Next_Array[x] If Key_Arrray[x] = k then Return x Exit Print (“not found”) 17b) Max Heapify (A, i) 1 l <-----Left(i) 2 e <-----Right (i) 3 if l <=heap-size [A] and A[l] >A[i] 4 then largest <---l 5 else largest <----i 6 if r<= heap-size [A] and A[r] >A[largest] 7 then largest <---r 8 if largest (nut equal) I 9 then exchange A[i] <---> A[largest] 10 MAX-HEAPIFY (A, largest) 19. Q. Describe a recursive algorithm for finding both the maximu and minimum values in an array A of n elements. Your algorithm should return a pair (a, B) where "a" is the minimum and "b" is the maximum. Need to be recursive fix if u can MinMax(A) 1 a ← Min(A) 2 b ← Max(A) 3 return a, b Min(A) 1 if lenght[A] = 0 then 2 then error "Array empty" 3 else smallest ← A[1] 4 for i ← 2 to Length[A] - 1 5 do if A[i] < smallest 6 then smallest ← A[i] 7 return smallest