DM507 - Algoritmer og Datastrukturer Project 1

Similar documents
Mergesort and Recurrences (CLRS 2.3, 4.4)

Midterm Exam. CS 3110: Design and Analysis of Algorithms. June 20, Group 1 Group 2 Group 3

Lecture 4. Quicksort

Lecture 5: Loop Invariants and Insertion-sort

Fundamental Algorithms

Fundamental Algorithms

Methods for solving recurrences

Outline. 1 Introduction. Merging and MergeSort. 3 Analysis. 4 Reference

Divide and Conquer Strategy

Divide and Conquer. Arash Rafiey. 27 October, 2016

The maximum-subarray problem. Given an array of integers, find a contiguous subarray with the maximum sum. Very naïve algorithm:

Introduction to Divide and Conquer

COL106: Data Structures and Algorithms (IIT Delhi, Semester-II )

CIS 121. Analysis of Algorithms & Computational Complexity. Slides based on materials provided by Mary Wootters (Stanford University)

Advanced Analysis of Algorithms - Midterm (Solutions)

Central Algorithmic Techniques. Iterative Algorithms

A design paradigm. Divide and conquer: (When) does decomposing a problem into smaller parts help? 09/09/ EECS 3101

COMP Analysis of Algorithms & Data Structures

Algorithms and Their Complexity

COMP Analysis of Algorithms & Data Structures

Solutions. Problem 1: Suppose a polynomial in n of degree d has the form

University of New Mexico Department of Computer Science. Midterm Examination. CS 361 Data Structures and Algorithms Spring, 2003

COMP 382: Reasoning about algorithms

Analysis of Algorithms - Using Asymptotic Bounds -

Homework 1 Submission

Lecture 3. Big-O notation, more recurrences!!

Topic Contents. Factoring Methods. Unit 3: Factoring Methods. Finding the square root of a number

Divide and Conquer Algorithms. CSE 101: Design and Analysis of Algorithms Lecture 14

Algorithms. Quicksort. Slide credit: David Luebke (Virginia)

Problem 5. Use mathematical induction to show that when n is an exact power of two, the solution of the recurrence

CMPSCI611: Three Divide-and-Conquer Examples Lecture 2

ICS141: Discrete Mathematics for Computer Science I

CPS 616 DIVIDE-AND-CONQUER 6-1

Lecture 22: Multithreaded Algorithms CSCI Algorithms I. Andrew Rosenberg

Assignment 4. CSci 3110: Introduction to Algorithms. Sample Solutions

i=1 i B[i] B[i] + A[i, j]; c n for j n downto i + 1 do c n i=1 (n i) C[i] C[i] + A[i, j]; c n

Divide and Conquer. CSE21 Winter 2017, Day 9 (B00), Day 6 (A00) January 30,

V. Adamchik 1. Recurrences. Victor Adamchik Fall of 2005

Recommended readings: Description of Quicksort in my notes, Ch7 of your CLRS text.

MA008/MIIZ01 Design and Analysis of Algorithms Lecture Notes 3

Analysis of Algorithms I: Asymptotic Notation, Induction, and MergeSort

Review Of Topics. Review: Induction

Analysis of Algorithms

Week 5: Quicksort, Lower bound, Greedy

Algorithm Analysis Recurrence Relation. Chung-Ang University, Jaesung Lee

Big O 2/14/13. Administrative. Does it terminate? David Kauchak cs302 Spring 2013

Quiz 1 Solutions. Problem 2. Asymptotics & Recurrences [20 points] (3 parts)

Data structures Exercise 1 solution. Question 1. Let s start by writing all the functions in big O notation:

Lecture 14: Nov. 11 & 13

Big , and Definition Definition

Outline. 1 Introduction. 3 Quicksort. 4 Analysis. 5 References. Idea. 1 Choose an element x and reorder the array as follows:

CS 4407 Algorithms Lecture 2: Iterative and Divide and Conquer Algorithms

CS173 Running Time and Big-O. Tandy Warnow

Advanced Analysis of Algorithms - Homework I (Solutions)

Solving recurrences. Frequently showing up when analysing divide&conquer algorithms or, more generally, recursive algorithms.

Lecture 2: MergeSort. CS 341: Algorithms. Thu, Jan 10 th 2019

1. Problem I calculated these out by hand. It was tedious, but kind of fun, in a a computer should really be doing this sort of way.

Lecture 6 September 21, 2016

CS161: Algorithm Design and Analysis Recitation Section 3 Stanford University Week of 29 January, Problem 3-1.

Partition and Select

Outline. 1 Merging. 2 Merge Sort. 3 Complexity of Sorting. 4 Merge Sort and Other Sorts 2 / 10

Lecture 6: Introducing Complexity

b + O(n d ) where a 1, b > 1, then O(n d log n) if a = b d d ) if a < b d O(n log b a ) if a > b d

Data Structures and Algorithms Chapter 3

Quicksort. Where Average and Worst Case Differ. S.V. N. (vishy) Vishwanathan. University of California, Santa Cruz

Quicksort (CLRS 7) We previously saw how the divide-and-conquer technique can be used to design sorting algorithm Merge-sort

Fall 2016 Test 1 with Solutions

5 + 9(10) + 3(100) + 0(1000) + 2(10000) =

k 6, then which of the following statements can you assume to be

Matrix Multiplication

Data selection. Lower complexity bound for sorting

O Notation (Big Oh) We want to give an upper bound on the amount of time it takes to solve a problem.

Data Structures and Algorithm Analysis (CSC317) Randomized Algorithms (part 3)

Analysis of Algorithms. Randomizing Quicksort

CSE373: Data Structures and Algorithms Lecture 3: Math Review; Algorithm Analysis. Catie Baker Spring 2015

Lecture 2: Divide and conquer and Dynamic programming

CSE548, AMS542: Analysis of Algorithms, Spring 2014 Date: May 12. Final In-Class Exam. ( 2:35 PM 3:50 PM : 75 Minutes )

5. Program Correctness: Mechanics

CSE 21 Practice Exam for Midterm 2 Fall 2017

CS483 Design and Analysis of Algorithms

CSCI 3110 Assignment 6 Solutions

Recursion: Introduction and Correctness

Big-O Notation and Complexity Analysis

Data Structures and Algorithms Chapter 2

Problem Decomposition: One Professor s Approach to Coding

Sorting. Chapter 11. CSE 2011 Prof. J. Elder Last Updated: :11 AM

Problem Set 1 Solutions

Computational Complexity

Another Proof By Contradiction: 2 is Irrational

CPSC 320 (Intermediate Algorithm Design and Analysis). Summer Instructor: Dr. Lior Malka Final Examination, July 24th, 2009

CS 4104 Data and Algorithm Analysis. Recurrence Relations. Modeling Recursive Function Cost. Solving Recurrences. Clifford A. Shaffer.

CSE 613: Parallel Programming. Lecture 8 ( Analyzing Divide-and-Conquer Algorithms )

Divide&Conquer: MergeSort. Algorithmic Thinking Luay Nakhleh Department of Computer Science Rice University Spring 2014

COMP 250: Quicksort. Carlos G. Oliver. February 13, Carlos G. Oliver COMP 250: Quicksort February 13, / 21

Lecture 2: Asymptotic Notation CSCI Algorithms I

Divide-Conquer-Glue. Divide-Conquer-Glue Algorithm Strategy. Skyline Problem as an Example of Divide-Conquer-Glue

CS 361, Lecture 14. Outline

CS 577 Introduction to Algorithms: Strassen s Algorithm and the Master Theorem

CS1802 Week 11: Algorithms, Sums, Series, Induction

Problem Set 2 Solutions

Transcription:

DM507 - Algoritmer og Datastrukturer Project 1 Christian Skjøth Mat-Øk 280588 Morten Olsen Mat-Øk 090789 19. marts 2012 Task 1 - Double for-loop So, first we needed to create an instance of the class File using the filename passed as an argument when the program was called. Then we needed to build an array from this file. And finally we had to count the number of inversions in the array. So our main function ended up looking like this: public s t a t i c void main ( S t r i n g [ ] a r g s ) throws Exception { / c r e a t e an i n s t a n c e o f t h e c l a s s F i l e from t h e g i v e n f i l e n a m e when t h e f u n c t i o n i s c a l l e d such t h a t we are a b l e to read data from t h i s f i l e F i l e f i l = new F i l e ( a r g s [ 0 ] ) ; / c r e a t e an array c o n t a i n i n g t h e i n t e g e r s in t h e g i v e n f i l e int [ ] dr= buildarrayfromfile ( f i l ) ; / p r i n t t h e number o f i n v e r s i o n s in t h e array to t h e command prompt System. out. p r i n t l n ( c o u n t I n v e r s i o n s ( dr ) ) ; So, we need to make two methods in this program, that is "buildarrayfromfile"and "countinversions". The first of the two is quite simple, however since we do not know the size of the array in the file in advance, we have chosen to create an ArrayList into which the integers from the file provided as parameter are initially stored. Then an array with the same "size"as the ArrayList is created and the values from ArrayList are copied to the array which is then returned. Thus "buildarrayfromfile"ended up looking like this: private s t a t i c int [ ] buildarrayfromfile ( F i l e f i l ){ L i s t <I n t e g e r > l i s t = new ArrayList <I n t e g e r >(); try{ Scanner s = new Scanner ( f i l ) ; while ( s. hasnextint ( ) ) { int i=s. n e x t I n t ( ) ; 1

l i s t. add ( i ) ; catch ( FileNotFoundException e ){ System. out. p r i n t l n ( " F i l e Not Found! " ) ; int [ ] array=new int [ l i s t. s i z e ( ) ] ; for ( int i =0; i < l i s t. s i z e ( ) ; i ++){ array [ i ]= l i s t. get ( i ) ; return array ; "countinversions"is extremely simple. Using the double for-loop, if n is the number of integers in the array, we iterate though the first n 1 integers of the array and for each integer k i (i = 1, 2,.., n), we iterate through the remaining n i integers checking whether these are bigger than k i. If that is the case, the counter is incremented by 1. When the array has been fully processed, the counter is then returned to the main function and printed to the screen. This is the code for the countinversions function: private s t a t i c int c o u n t I n v e r s i o n s ( int [ ] dr ){ int count =0; try{ for ( int i =0; i <dr. length 1; i ++){ for ( int j=i +1; j<dr. l e n g t h ; j ++){ i f ( dr [ j ]< dr [ i ] ) { count++; catch ( Exception e ){ System. out. p r i n t l n ( " There were no numbers i n the given f i l e " ) ; return count ; Task 2 - Using Pseudo Code Our main function is very similar to the previous task and the buildarrayfrom- File is exactly the same, so we are not going to elaborate on these. So we have 2 functions, mergesort and Merge which are based on the pseudo code in the book. Let us start with mergesort. The biggest challenge with this function was the secure that it actually returned an array to the main function. So we had to make Merge return an array which is the returned to main. Also, note that when the function is called recursively at some point one will end up processing only 1 integer. This is obviously already sorted and is therefore returned directly to the previous call of function mergesort. Finally, since we have chosen q to be an integer, we will get a number which is already rounded down following division. private s t a t i c int [ ] mergesort ( int [ ] dr, int p, int r ){ i f ( p<r ){ 2

int q=(p+r ) / 2 ; mergesort ( dr, p, q ) ; mergesort ( dr, q+1, r ) ; return Merge ( dr, p, q, r ) ; else { return dr ; Then we had to implement Merge. This was pretty easy. The only thing we really had to do was to account for 0-indexing in java whereas the book uses 1-indexing and of course we had to make sure the sorted array is returned to mergesort where Merge is called. The code is as stated below: private s t a t i c int [ ] Merge ( int [ ] dr, int p, int q, int r ){ int l l e n g t h = q p + 1 ; int r l e n g t h = r q ; int [ ] L = new int [ l l e n g t h +1]; int [ ] R = new int [ r l e n g t h +1]; for ( int i =0; i <l l e n g t h ; i ++){ L [ i ]= dr [ p+i ] ; for ( int j =0; j<r l e n g t h ; j ++){ R[ j ]= dr [ q+j +1]; L [ l l e n g t h ]= I n t e g e r.max_value; R[ r l e n g t h ]= I n t e g e r.max_value; int i =0; int j =0; for ( int k=p ; k<=r ; k++){ i f (L [ i ]<=R[ j ] ) { dr [ k]=l [ i ] ; i ++; else { dr [ k]=r[ j ] ; j ++; return dr ; Task 3 So the initial array is divided into 2 subarrays. Every time an integer from the R-subarray is lower than a non- integer from the L-subarray, there is an inversion. Then the zcounter will be incremented by q + 1 (p + i). If we would want to state it in code it would be: int i =0; int j =0; int zcounter =0; for ( int k=p ; k<=r ; k++){ i f (L [ i ]<=R[ j ] ) { dr [ k]=l [ i ] ; 3

i ++; else { dr [ k]=r[ j ] ; j ++; zcounter += q+1 (p+i ) ; Task 4 This algorithm is of course correct, since we were the ones to design it! Anyways, as Initialization: Prior to the first iteration of the loop, we have zcounter = i = j = 0 which is the same as z minus the the number of inversions (s, t) in A[p..r] with endpoints in A[(p + i = p)..q] and A[(q + j + 1 = q + 1)..r] (i.e. the number of inversions in the entire array). To see that each iteration maintains the loop invariant, let us first suppose that L[i] R[j], then zcounter will not be incremented because L[i] is thus smaller than or equal to every element in A[(q + j + 1)..r], so there are no inversions between A[(p + i)] and A[(q + j + 1)..r]. So i increments by 1 and thus zcounter is still equal z minus the inversions (s, t) in A[p..r] with endpoints in A[(p + i)..q] and A[(q + j + 1)..r]. On the other hand suppose that L[i] > R[j], then zcounter will be incremented because all the elements in A[(p + i)..q] are thus smaller than every element in A[(q+j +1)..r] (because A[(p+i)..q] is already sorted), so there are q+1 (p+i) inversions between A[(p + i)..q] and A[(q + j + 1)]. So j increments by 1 and zcounter increments by q + 1 (p + i) and thus zcounter is still equal z minus the inversions (s, t) in A[p..r] with endpoints in A[(p + i)..q] and A[(q + j + 1)..r] and the loop invariant is maintained. At termination i = q p + 1 and j = r (q + 1) + 1 and thus zcounter equals z minus the number of inversions (s, t) in A[p..r] with endpoints in A[(p + i = p+q p = q +1)..q] which makes no sense and A[(q +(r (q +1))+1 = r +1)..r] which also does not make any sense. But we do know that zcounter by this point is the number of inversions (s, t) in A[p..r] with endpoints in A[p..q] and A[(q + 1)..r] which is the number of inversions in the entire array A[p..r] and so equals z because there are no remaining inversions. The second part of this task (the runtime) is pretty well described on the bottom of page 30 and the top of page 31. Suppose we have n integers, the worst case maximum increase in runtime as opposed to the runtime of the version without z will be c 1 + n 2 (c 2) with c 1 being the cost of initializing zcounter, and c 2 the cost of incrementing zcounter by q + 1 (p + i). But an additional runtime of c 1 + n 2 (c 2) does not change the Θ runtime stated in the book of the simplified version which is Θ(n). Task 5 Okay, so since we already know how to calculate z by using Merge, we need only compute x and y and the sum of these 3 values will be the number of inversions 4

in the array. Now since every subarray can be treated as an independent array, we can continue to call mergesort recursively on these subarray until we have arrays of length 1. Obviously these are sorted, so our "sub-x"and "sub-y"are set to 0. We then use Merge to calculate our "sub-z"and the sum of these 3 is the number of inversions in an array of length 2. This will again become a new "sub-x"and together with the corresponding "sub-y"and "sub-z", the sum of these 3 will become the total number of inversions in a subarray of size 3 or 4. If we keeping pairing these sums and calculating the corresponding z s, we should end up with the total number of inversions in the entire array. The algorithm would look like 1. check whether the given array has more than 1 element, if not return 0 2. divide the array into 2 subarrays 3. find the sum of inversions in each of these two subarrays by going to step 1 for each subarray 4. find the number of inversions between the two subarrays using the improved Merge 5. return the sum from step 4 + the number from step 5 Task 6 We will use induction. For the base case, consider an array of length 1. This is already sorted and does not contain any inversions, so the base case is correct. For the induction step, suppose that MergeSort will sort any array with less than n elements and return the correct number of inversions in these. So if we call MergeSort on an array of length n, it will then recursively call MergeSort on two arrays of length n/2. These are sorted correctly and the correct number of inversions are returned according to the induction hypothesis. So after recursion the two subarrays A[p..q] and A[q + 1..r] are both sorted and the correct number of inversions in both are returned. We have already argued that our Merge works, and thus after this is executed, the array is sorted correctly and the sum of inversions in each subarray plus the number of inversions between the 2 is the total number of inversion in the entire array A. This concludes that this algorithm must be correct. In terms of runtime. We have only added a constant amount of work to each procedure call and to each iteration of the last for-loop in the Merge procedure. Therefore the total running of the algorithm is the same as for merge sort, i.e. Θ(n log n). But it is probably required to use the Master Theorem. So we will also do this. Lets denote the total runtime T (n). Since each array will be recursively subdivided into 2 subarrays and then merged, we may write T (n) = 2T ( n 2 ) + f(n) with f(n) being the time of merging, i.e. Θ(n). We now see that the master theorem can be applied on T (n) with a = b = 2. We now realize that f(n) = Θ(n log 2 (2) ) = Θ(n) 5

and therefore T (n) = Θ(n log 2 (2) log 2 (n)) = Θ(n log 2 (n)) Task 7 Everything in this implementation has already been discussed or is trivial, so we refer to the source code in the appendix. 6

Appendix SimpleInv.java import java. u t i l. ; import java. i o. ; public class SimpleInv { / main c l a s s. counts t h e number o f i n v e r s i o n s in an array contained in a f i l e whose name i s g i v e n when t h e f u n c t i o n i s c a l l e d public s t a t i c void main ( S t r i n g [ ] a r g s ) throws Exception { / c r e a t e an i n s t a n c e o f t h e c l a s s F i l e from t h e g i v e n f i l e n a m e when t h e f u n c t i o n i s c a l l e d such t h a t we are a b l e to read data from t h i s f i l e F i l e f i l = new F i l e ( a r g s [ 0 ] ) ; / c r e a t e an array c o n t a i n i n g t h e i n t e g e r s in t h e g i v e n f i l e int [ ] dr= buildarrayfromfile ( f i l ) ; / p r i n t t h e number o f i n v e r s i o n s in t h e array to t h e command prompt System. out. p r i n t l n ( c o u n t I n v e r s i o n s ( dr ) ) ; / c r e a t e s an array c o n t a i n i n g t h e i n t e g e r s in t h e g i v e n f i l e in t h e same order t h e y were l i s t e d in t h e f i l e, by p a r s i n g through t h e f i l e and s t o r i n g every i n t e g e r encountered i n t o an ArrayList. Then an array i s c r e a t e d with t h e same s i z e as t h e ArrayList i n t o which t h e v a l u e s o f t h e ArrayList are copied. F i n a l l y t h e array c o n t a i n i n g t h e v a l u e s o f t h e f i l e s are returned private s t a t i c int [ ] buildarrayfromfile ( F i l e f i l ){ L i s t <I n t e g e r > l i s t = new ArrayList <I n t e g e r >(); try{ Scanner s = new Scanner ( f i l ) ; while ( s. hasnextint ( ) ) { int i=s. n e x t I n t ( ) ; l i s t. add ( i ) ; catch ( FileNotFoundException e ){ System. out. p r i n t l n ( " F i l e Not Found! " ) ; int [ ] array=new int [ l i s t. s i z e ( ) ] ; for ( int i =0; i < l i s t. s i z e ( ) ; i ++){ array [ i ]= l i s t. get ( i ) ; return array ; / r e t u r n s t h e number o f i n v e r s i o n s u sing a d o u b l e f o r l o o p private s t a t i c int c o u n t I n v e r s i o n s ( int [ ] dr ){ int count =0; 7

try{ for ( int i =0; i <dr. length 1; i ++){ for ( int j=i +1; j<dr. l e n g t h ; j ++){ i f ( dr [ j ]< dr [ i ] ) { count++; catch ( Exception e ){ System. out. p r i n t l n ( " There were no numbers i n the given f i l e " ) ; return count ; MergeSort.java import java. u t i l. ; import java. i o. ; public class MergeSort { public s t a t i c void main ( S t r i n g [ ] a r g s ) throws Exception { F i l e f i l = new F i l e ( a r g s [ 0 ] ) ; int [ ] dr= buildarrayfromfile ( f i l ) ; dr=mergesort ( dr, 0, dr. length 1); for ( int i =0; i <dr. l e n g t h ; i ++){ i f else { ( i==dr. length 1){ System. out. p r i n t l n ( dr [ i ] ) ; System. out. p r i n t ( dr [ i ]+" " ) ; private s t a t i c int [ ] buildarrayfromfile ( F i l e f i l ){ L i s t <I n t e g e r > l i s t = new ArrayList <I n t e g e r >(); try{ Scanner s = new Scanner ( f i l ) ; while ( s. hasnextint ( ) ) { int i=s. n e x t I n t ( ) ; l i s t. add ( i ) ; catch ( FileNotFoundException e ){ System. out. p r i n t l n ( " F i l e Not Found! " ) ; int [ ] array=new int [ l i s t. s i z e ( ) ] ; for ( int i =0; i < l i s t. s i z e ( ) ; i ++){ array [ i ]= l i s t. get ( i ) ; return array ; / D i v i d e s t h e e n t i r e array u sing r e c u r s i o n and s o r t s t h e s u b a r r a y s 8

private s t a t i c int [ ] mergesort ( int [ ] dr, int p, int r ){ i f ( p<r ){ int q=(p+r ) / 2 ; mergesort ( dr, p, q ) ; mergesort ( dr, q+1, r ) ; return Merge ( dr, p, q, r ) ; else { return dr ; / S o r t s an array by d i v i d i n g i t i n t o 2 subarray and then compares t h e elements to see which s m a l l e r private s t a t i c int [ ] Merge ( int [ ] dr, int p, int q, int r ){ int l l e n g t h = q p + 1 ; int r l e n g t h = r q ; int [ ] L = new int [ l l e n g t h +1]; int [ ] R = new int [ r l e n g t h +1]; for ( int i =0; i <l l e n g t h ; i ++){ L [ i ]= dr [ p+i ] ; for ( int j =0; j<r l e n g t h ; j ++){ R[ j ]= dr [ q+j +1]; L [ l l e n g t h ]= I n t e g e r.max_value; R[ r l e n g t h ]= I n t e g e r.max_value; int i =0; int j =0; FastInv.java for ( int k=p ; k<=r ; k++){ i f (L [ i ]<=R[ j ] ) { dr [ k]=l [ i ] ; i ++; else { dr [ k]=r[ j ] ; j ++; return dr ; import java. u t i l. ; import java. i o. ; public class FastInv { public s t a t i c void main ( S t r i n g [ ] a r g s ) throws Exception { F i l e f i l = new F i l e ( a r g s [ 0 ] ) ; int [ ] dr= buildarrayfromfile ( f i l ) ; System. out. p r i n t l n ( mergesort ( dr, 0, dr. length 1)); private s t a t i c int [ ] buildarrayfromfile ( F i l e f i l ){ L i s t <I n t e g e r > l i s t = new ArrayList <I n t e g e r >(); try{ Scanner s = new Scanner ( f i l ) ; 9

while ( s. hasnextint ( ) ) { int i=s. n e x t I n t ( ) ; l i s t. add ( i ) ; catch ( FileNotFoundException e ){ System. out. p r i n t l n ( " F i l e Not Found! " ) ; int [ ] array=new int [ l i s t. s i z e ( ) ] ; for ( int i =0; i < l i s t. s i z e ( ) ; i ++){ array [ i ]= l i s t. get ( i ) ; return array ; / r e t u r n s t h e number o f i n v e r s i o n s in an array u sing r e c u r s i o n to d i v i d e t h e array i n t o s u b a r r a y s from whom t h e number o f i n v e r s i o n s are r eturned private s t a t i c int mergesort ( int [ ] dr, int p, int r ){ i f ( p<r ){ int q=(p+r ) / 2 ; int z t o t = mergesort ( dr, p, q ) + mergesort ( dr, q+1, r ) ; z t o t += Merge ( dr, p, q, r ) ; return z t o t ; else {return 0 ; / r e t u r n s t h e number o f i n v e r s i o n in an array private s t a t i c int Merge ( int [ ] dr, int p, int q, int r ){ int l l e n g t h = q p + 1 ; int r l e n g t h = r q ; int [ ] L = new int [ l l e n g t h +1]; int [ ] R = new int [ r l e n g t h +1]; for ( int i =0; i <l l e n g t h ; i ++){ L [ i ]= dr [ p+i ] ; for ( int j =0; j<r l e n g t h ; j ++){ R[ j ]= dr [ q+j +1]; L [ l l e n g t h ]= I n t e g e r.max_value; R[ r l e n g t h ]= I n t e g e r.max_value; int i =0; int j =0; int zcounter =0; for ( int k=p ; k<=r ; k++){ i f (L [ i ]<=R[ j ] ) { dr [ k]=l [ i ] ; i ++; else { dr [ k]=r[ j ] ; j ++; zcounter += l l e n g t h i ; 10

return zcounter ; 11