Algorithms_Part4 - S. Dasgupta, C.H. Papadimitriou, and...

Info iconThis preview shows pages 1–4. Sign up to view the full content.

View Full Document Right Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: S. Dasgupta, C.H. Papadimitriou, and U.V. Vazirani 61 Figure 2.4 The sequence of merge operations in mergesort . 2 3 10 1 6 7 13 5 10 2 5 3 13 7 1 6 2 5 3 7 13 1 6 10 Input: 10 2 3 1 13 5 7 6 1 6 10 13 3 2 5 7 . function merge ( x [1 . . . k ] , y [1 . . . l ] ) if k = 0 : return y [1 . . . l ] if l = 0 : return x [1 . . . k ] if x [1] ≤ y [1] : return x [1] ◦ merge ( x [2 . . . k ] , y [1 . . . l ]) else: return y [1] ◦ merge ( x [1 . . . k ] , y [2 . . . l ]) Here ◦ denotes concatenation. This merge procedure does a constant amount of work per recursive call (provided the required array space is allocated in advance), for a total running time of O ( k + l ) . Thus merge ’s are linear, and the overall time taken by mergesort is T ( n ) = 2 T ( n/ 2) + O ( n ) , or O ( n log n ) . Looking back at the mergesort algorithm, we see that all the real work is done in merg- ing, which doesn’t start until the recursion gets down to singleton arrays. The singletons are merged in pairs, to yield arrays with two elements. Then pairs of these 2-tuples are merged, producing 4-tuples, and so on. Figure 2.4 shows an example. This viewpoint also suggests how mergesort might be made iterative. At any given mo- ment, there is a set of “active” arrays—initially, the singletons—which are merged in pairs to give the next batch of active arrays. These arrays can be organized in a queue, and processed by repeatedly removing two arrays from the front of the queue, merging them, and putting the result at the end of the queue. 62 Algorithms In the following pseudocode, the primitive operation inject adds an element to the end of the queue while eject removes and returns the element at the front of the queue. function iterative-mergesort ( a [1 . . . n ] ) Input: elements a 1 , a 2 , . . . , a n to be sorted Q = [ ] (empty queue) for i = 1 to n : inject ( Q, [ a i ]) while | Q | > 1 : inject ( Q, merge ( eject ( Q ) , eject ( Q ))) return eject ( Q ) S. Dasgupta, C.H. Papadimitriou, and U.V. Vazirani 63 An n log n lower bound for sorting Sorting algorithms can be depicted as trees. The one in the following figure sorts an array of three elements, a 1 , a 2 , a 3 . It starts by comparing a 1 to a 2 and, if the first is larger, compares it with a 3 ; otherwise it compares a 2 and a 3 . And so on. Eventually we end up at a leaf, and this leaf is labeled with the true order of the three elements as a permutation of 1 , 2 , 3 . For example, if a 2 < a 1 < a 3 , we get the leaf labeled “ 2 1 3 .” 3 2 1 Yes a 2 < a 3 ? a 1 < a 2 ? a 1 < a 3 ? a 2 < a 3 ? a 1 < a 3 ? 2 3 1 2 1 3 3 1 2 1 3 2 1 2 3 No The depth of the tree—the number of comparisons on the longest path from root to leaf, in this case 3 —is exactly the worst-case time complexity of the algorithm....
View Full Document

Page1 / 20

Algorithms_Part4 - S. Dasgupta, C.H. Papadimitriou, and...

This preview shows document pages 1 - 4. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online