Run time typically depends on: How long things take to set up How many operations there are in each step How many steps there are Insertion sort can be faster than merge sort One array, one operation per step But N*log(N) eventually beats N^2 for large N And once it does, the advantage increases rapidly Fast, able to handle any data But can t be done in place View the array as a set of small sorted arrays Initially only the 1-element arrays are sorted Merge pairs of sorted arrays Repeatedly choose the smallest element in each This produces sorted arrays that are twice as long Repeat until only one array remains 27 31 4
27 31 4 27 31 4 27 31 27 31 4 27 31 4 27 31 27 31 4 27 31 4
27 31 4 27 31 4 27 31 4 4 27 31 Statement Effort MergeSort(A, lower_bound, upper_bound) T(n) if (lower_bound < upper_bound) Θ(1) mid = (lower_bound + upper_bound)/ 2 Θ(1) MergeSort(A, lower_bound, mid) T(n/2) MergeSort(A, mid+1, upper_bound) T(n/2) Merge(A, lower_bound, mid,upper_bound) Θ(n) end So T(n) = Θ(1) when n = 1, and 2T(n/2) + Θ(n) when n > 1 So what (more succinctly) is T(n)? The expression: c n = 1 T ( n) = n 2T + c n > 1 2 is a recurrence. Recurrence: an equation that describes a function in terms of its value on smaller functions
Each array size requires N steps But 8 elements requires only 3 array sizes In general, 2 elements k requires k array sizes So the complexity is N*log(N) No faster sort (based on comparisons) exists Faster sorts require assumptions about the data There are other N*log(N) sorts, though Merge sort is most often used for large disk files Split a problem into simpler subproblems Keep doing that until trivial subproblems result Solve the trivial subproblems Combine the results to solve a larger problem Keep doing that until the full problem is solved Merge sort illustrates divide and conquer But it is a general strategy that is often helpful The visibility rules determine which declarations are visible and directly visible at each place within a program. The visibility rules apply to both explicit and implicit declarations Direct Visibility immediate visibility use-visibility In general, a subprogram call involves: 1. save execution status of the calling program unit 2. parameter passing 3. pass address to subprogram 4. transfer control to subprogram possibly: allocate local variables, provide access to nonlocals in general, a subprogram involves: 1. if out-mode parameters or value, pass back value(s) 2. deallocate parameters, local variables 3. restore non-local variable environment 4. transfer control to the calling program unit
No Information Flow (No Parameters) procedure <procedure name> is <procedure name> - the name of the procedure. With Information Flow (With Parameters) procedure <procedure name> ( <formal parameter name> : <mode> <data type>; <formal parameter name> : <mode> <data type>;... ) is <procedure name> - the name of the procedure. <formal parameter name> - the name of a parameter. <mode> - the mode (in, out, or in out) of the parameter. <data type> - the data type for the parameter.! Implementation method is determined by the compiler in by-value out by-result in out by-value-result (for non-structured types) by-value-result or by-reference (for structured types) choice of in out method for structured types is implementation dependent!! By Value Parameter is treated as local variable Initialized to argument value By Result Parameter is treated as a local variable with no initialization When the function terminates, the value of the parameter is passed to the argument By Value Result (In Out) Combination of by-value and by-result methods Treated as local variable, initialized to argument, passed back when done If the subprogram is independent of invocation (e.g., constants, instructions) => store in code segment If info is dependent upon the particular invocation (e.g., value, parameters, local variables ) => must store an activation record for each invocation Activation Record local variables parameters link link address
"# "#$ %& when a subroutine is called, an instance of its activation record is pushed program MAIN; procedure is print a; end procedure is a := 0; end ; a := 7; ; end Main; a =? MAIN called a =? called a = 0 called when a subroutine terminates, its activation record is popped (note LIFO behavior) program MAIN; procedure is print a; end procedure is a := 0; end ; a := 7; ; end Main; a = 0 called a =? when the last activation record is popped, control s to the operating system terminates terminates "#$ %& Note: the same subroutine may be called from different points in the program program MAIN; procedure is print a; end procedure is a := 0; end ; a := 7; ; end Main; a = 0 1st call to 2nd call to the same variable in a subroutine may refer to a different addresses at different times