program memory allocation

32
Carrano - Chapter 2 CS 150 1 Program Memory Allocation Program B’s Run-Time Stack (Room for B’s growth) Program B’s Data Heap Program B Program A’s Run-Time Stack (Room for A’s growth) Program A’s Data Heap Program A Operating System Each program being executed on a computer is allocated extra space which it could use for its stack of function calls, and/or for “dynamically” expanding its use of memory for data. The memory used for data is known as a “heap”.

Upload: chelsi

Post on 22-Jan-2016

33 views

Category:

Documents


6 download

DESCRIPTION

Program B’s Run-Time Stack.  ( Room for B’s growth ) . Program B’s Data Heap. Program B. Program A’s Run-Time Stack.  ( Room for A’s growth ) . Program A’s Data Heap. Program A. Operating System. Program Memory Allocation. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Program Memory Allocation

Carrano - Chapter 2 CS 150 1

Program Memory Allocation

Program B’s Run-Time Stack

(Room for B’s growth)

Program B’s Data Heap

Program B

Program A’s Run-Time Stack

(Room for A’s growth)

Program A’s Data Heap

Program A

OperatingSystem

Each program being executed on a computer is allocated extra space which it could use for its stack of function calls, and/or for “dynamically” expanding its use of memory for data. The memory used for data is known as a “heap”.

Page 2: Program Memory Allocation

Carrano - Chapter 2 CS 150 2

A Program’s Run-Time StackProgram XYZ:

void main(){ int snap = 7; int yap = 10; int blap = 100; blap = snippy(snap); yippy(yap, blap); zippy(yap);}int snippy(int snoo){ int hep = yippy(snoo,5); if (hep > 0) return hep; else return 0;}void yippy(int &yoo, int boo){ int i; for (i = 1; i < boo; i++) yoo += i; return;}void zippy(int zoo){ cout << zoo << endl; }

snap: 7

yap: 10

blap: 100

void main(){ int snap = 7; int yap = 10; int blap = 100; blap = snippy(snap); yippy(yap, blap); zippy(yap);}

snoo: 7

hep: ???

int snippy(int snoo){ int hep = yippy(snoo,5); if (hep > 0) return hep; else return 0;}

yoo:

boo: 5

int yippy(int &yoo, int boo){ int i; for (i = 1; i < boo; i++) yoo += i; return boo + yoo;}

i: 5

Page 3: Program Memory Allocation

Carrano - Chapter 2 CS 150 3

RecursionIt is sometimes useful to have a function call itself, making it a recursive function. This approach often enables the programmer to solve a problem by repeatedly solving smaller, more manageable versions of the problem, until the original problem’s solution becomes apparent.

Care must be taken when using recursion, however. Because a new incarnation of the function is placed upon the run-time stack each time the function is recursively called, there is a danger that the stack will overflow.

To prevent this from happening, the function must contain a termination condition, which will recognize when the recursion should halt, and pop the current incarnation of the recursive function off of the run-time stack.

Page 4: Program Memory Allocation

Carrano - Chapter 2 CS 150 4

Recursion Example #1: Factorial////////////////////////////////////////////////////////////////////////////// Program file: factorial.cpp //// This program queries the user for a non-negative integer and then uses //// a recursive function to calculate the factorial of the input value. //////////////////////////////////////////////////////////////////////////////#include <iostream>#include <iomanip>

using namespace std;

int factorial(int n);

////////////////////////////////////////////////////////////// The main function asks the user for a value, calls the //// recursive factorial function, and outputs the result. //////////////////////////////////////////////////////////////void main(){ int number, result;

cout << "Enter a non-negative integer for factorial computation: "; cin >> number; while (number < 0) { cout << "I said, enter a NON-NEGATIVE integer: "; cin >> number; } cout << endl;

result = factorial(number); cout << "FINAL RESULT: " << number << "! = " << result << endl << endl;

}

Page 5: Program Memory Allocation

Carrano - Chapter 2 CS 150 5

Factorial (Continued)

/////////////////////////////////////////////////////////////////////////////// Function factorial recursively calculates the factorial of parameter n, //// outputting entering and exiting messages to demonstrate to the user the //// recursive function calls which make the final calculation possible. ///////////////////////////////////////////////////////////////////////////////int factorial(int n){ static int indent = 0; int result;

cout << setw(indent) << "" << "ENTERING FACTORIAL ROUTINE WITH N = ” << n << endl << endl; if ((n == 1) || (n == 0)) { cout << setw(indent) << "" << "EXITING FACTORIAL ROUTINE WITH N = " << n << ", " << n << "! = " << 1 << endl << endl; indent -= 4; return 1; } else { indent += 4; result = n * factorial(n - 1); cout << setw(indent) << "" << "EXITING FACTORIAL ROUTINE WITH N = " << n << ", " << n << "! = " << result << endl << endl; indent -= 4; return result; }}

Page 6: Program Memory Allocation

Carrano - Chapter 2 CS 150 6

Factorial (Continued)

Page 7: Program Memory Allocation

Carrano - Chapter 2 CS 150 7

Tracing Through Factorial’s Run-Time Stack

number: 5

void main(){ : result = factorial(number); :}

n: 5

result: 5*?

int factorial (int n){ if ((n == 1) || (n == 0)) return 1; else { result = n * factorial(n-1); return result; }}

n: 4

result: 4*?

int factorial (int n){ if ((n == 1) || (n == 0)) return 1; else { result = n * factorial(n-1); return result; }}

n: 3

result: 3*?

int factorial (int n){ if ((n == 1) || (n == 0)) return 1; else { result = n * factorial(n-1); return result; }}

n: 2

result: 2*?

int factorial (int n){ if ((n == 1) || (n == 0)) return 1; else { result = n * factorial(n-1); return result; }}

n: 1

result: ?

int factorial (int n){ if ((n == 1) || (n == 0)) return 1; else :}

result: ?

Page 8: Program Memory Allocation

Carrano - Chapter 2 CS 150 8

Recursion Example #2: Exponentiation//////////////////////////////////////////////////////////////////////////////// Program file: exponent.cpp //// This program queries the user for a floating-point base and an integer //// exponent, and then uses a recursive function to calculate the value of //// the base raised to the power. ////////////////////////////////////////////////////////////////////////////////

#include <iostream>#include <iomanip>

using namespace std;

double exponentiate(double base, int power);

//////////////////////////////////////////////////////////////// The main function asks the user for a value, calls the //// recursive exponentiate function, and outputs the result. ////////////////////////////////////////////////////////////////void main(){ double base, result; int power;

cout << "Enter a floating-point base value: "; cin >> base; cout << "Enter an integer exponent: "; cin >> power; cout << endl;

result = exponentiate(base, power);

cout << endl << "FINAL RESULT: " << base << '^' << power

<< " = " << result << endl << endl;

}

Page 9: Program Memory Allocation

Carrano - Chapter 2 CS 150 9

Exponentiation (Continued)//////////////////////////////////////////////////////////////////////////////// Function exponentiate recursively calculates the value of raising //// parameter base to the parameter power's exponent, outputting entering //// and exiting messages to demonstrate to the user the recursive function //// calls which make the final calculation possible. ////////////////////////////////////////////////////////////////////////////////double exponentiate(double base, int power){ static int indent = 0; double result; cout.setf(ios::fixed); cout << setprecision(8) << setw(indent) << "" << "ENTERING EXPONENTIATE ROUTINE WITH POWER = ” << power << endl; if (power == 0) result = 1.0; else if (power > 0) { indent++; result = base * exponentiate(base, power - 1); } else { indent++; result = exponentiate(base, power + 1) / base; } cout << setw(indent) << "" << "EXITING EXPONENTIATE ROUTINE WITH POWER = " << power << ", " << base << '^' << power << " = " << result << endl; indent--; return result;}

Page 10: Program Memory Allocation

Carrano - Chapter 2 CS 150 10

Exponentiation (Continued)

Page 11: Program Memory Allocation

Carrano - Chapter 2 CS 150 11

Recursion Example #3: Logarithm/////////////////////////////////////////////////////////////////////////////////// Program file: logarithm.cpp //// This program queries the user for a value and a base, then uses a recursive //// function to calculate the value of the logarithm of the value to the base. ///////////////////////////////////////////////////////////////////////////////////#include <iostream>#include <iomanip>#include <cmath>

using namespace std;

void queryUser(double &value, double &base);int myLog(double value, double base);

// Main asks the user for a value, calls recursive log, and outputs result. //void main(){ double value, base; char yORn; cout.setf(ios::fixed); cout << "Would you like to put a log on the fire? (Enter Y or N) "; cin >> yORn; while ((yORn == 'y') || (yORn == 'Y')) { queryUser(value, base); cout << "Approximate log: " << myLog(value, base) << endl << "Real log: " << log(value)/log(base) << endl << endl; cout << "Would you like to put another log on the fire? (Enter Y or N) "; cin >> yORn; }}

Page 12: Program Memory Allocation

Carrano - Chapter 2 CS 150 12

Logarithm (Continued)// Function queryUser asks the user for positive values for //// both the floating-point value and the logarithmic base. //void queryUser(double &value, double &base){ do { cout << "Enter a positive floating-point value: "; cin >> value; } while (value <= 0.0F); do { cout << "Enter a floating-point base (greater than one): "; cin >> base; } while (base <= 1.0F);}

// Function log recursively calculates the integer value of taking the //// logarithm (to the parameterized base) of the parameterized value. //int myLog(double value, double base){ int result; if ((value > 1/base) && (value < base)) result = 0; else if (value <= 1/base) result = myLog(value*base, base) - 1; else result = myLog(value/base, base) + 1; return result;}

Page 13: Program Memory Allocation

Carrano - Chapter 2 CS 150 13

Logarithm (Continued)

Page 14: Program Memory Allocation

Carrano - Chapter 2 CS 150 14

Recursion Example #4: Combination

Given n objects, how many different sets of size k can be selected?

This problem can be solved by solving two slightly smaller problems and summing the results (sounds pretty recursive!):

Problem 1: Assuming that the first object is selected, how many size k-1 sets can be selected from the remaining n-1 objects?

Problem 2: Assuming that the first object is not selected, how many size k sets can be selected from the remaining n-1 objects?

Page 15: Program Memory Allocation

Carrano - Chapter 2 CS 150 15

Combination (Continued)

/////////////////////////////////////////////////////////////////////// Program file: combination.cpp //// This program queries the user for a set size and a subset size, //// and then recursively computes the number of different subsets //// of the appropriate size that could be selected from the set. ///////////////////////////////////////////////////////////////////////#include <iostream>using namespace std;int computeCombo(int setSize, int subsetSize);

// Main asks the user for the set & subset sizes, calls the //// function producing the combination, and outputs the result. //void main(){ int sizeOfCollection; int sizeOfSelection; cout << "How many objects in the master collection? "; cin >> sizeOfCollection; cout << "How many objects in a single selection? "; cin >> sizeOfSelection; cout << endl << endl; cout << "FOR " << sizeOfCollection << " FANCY OBJECTS COLLECTED" << endl << "AND " << sizeOfSelection << " LUCKY CHOICES SELECTED," << endl << "THERE\'S " << computeCombo(sizeOfCollection, sizeOfSelection) << " DIFFERENT SUBSETS" << endl << "BUT EACH HAS " << sizeOfCollection-sizeOfSelection << " ANGRY UPSETS" << endl << "\'CAUSE THE REST OF THE SAPS ARE REJECTED!" << endl << endl;}

Page 16: Program Memory Allocation

Carrano - Chapter 2 CS 150 16

Combination (Continued)/////////////////////////////////////////////////////////////// Function computeCombo recursively calculates the number //// of different combinations of size subsetSize that can //// be obtained from a collection of size setSize. ///////////////////////////////////////////////////////////////int computeCombo(int setSize, int subsetSize){if ((subsetSize == 0) || (subsetSize == setSize))

return 1;if (subsetSize > setSize)

return 0; return (computeCombo(setSize-1, subsetSize-1) +

computeCombo(setSize-1, subsetSize));}

Page 17: Program Memory Allocation

Carrano - Chapter 2 CS 150 17

Recursion Example #5: Binary Search

// Library header file: boolean.h

#ifndef BOOL_H

#undef TRUE#undef FALSE

const int TRUE = 1;const int FALSE = 0;

typedef int boolean;

#define BOOL_H#endif

While it’s a lot easier to write a program that searches a sorted list by merely looping through the whole list (i.e., a sequential, or linear, search), it’s not exactly an efficient way of getting the job done.

A more efficient approach is to use a “binary search”: Look at the middle element of the list. If that’s the value you seek, then you’re done. If it’s not, then it’s either larger or smaller than the value you seek. Since the list is sorted, you can just proceed with either the first half of the list (if the middle value was larger) or the second half (if the middle value was smaller). In either case, you’ve cut the “size” of the problem in half. That’s recursion!

Let’s begin by creating our own boolean type, to make our code easier to read.

Just make sure to include this homemade header file in the program, and to add it to the project when you try to build the executable file.

Page 18: Program Memory Allocation

Carrano - Chapter 2 CS 150 18

Binary Search (Continued)////////////////////////////////////////////////////////////// Program file: binarySearch.cpp //// This program sets up a sorted list of integers, and //// then allows the user to interactively search the //// list for values by means of a recursive binary search. //////////////////////////////////////////////////////////////#include <iostream>#include <cstdlib>#include <ctime>#include "boolean.h"using namespace std;const LIST_SIZE = 100;const HI_RAND_INT = 32767;

void generateList(int list[]);int randomValue(int lowerBound, int upperBound);boolean binSearch(const int list[], int firstIndex, int lastIndex, int soughtValue, int &correctIndex);

Page 19: Program Memory Allocation

Carrano - Chapter 2 CS 150 19

Binary Search (Continued)///////////////////////////////////////////////////////////// Main sets up the sorted list of integers, and then //// repeatedly asks the user for the for values to be //// found (or not found) via the recursive binary search. /////////////////////////////////////////////////////////////void main(){ int sortedList[LIST_SIZE]; int valueToFind; int location;

generateList(sortedList); cout << "RECURSIVE BINARY SEARCH TEST" << endl << endl; cout << "Enter a value to be sought in the list (use a negative value to quit): "; cin >> valueToFind; while (valueToFind > 0) { if (binSearch(sortedList, 0, LIST_SIZE-1, valueToFind, location)) cout << "Value " << valueToFind << " was found at index " << location << endl << endl; else cout << "Value " << valueToFind << " was not found in the list" << endl << endl; cout << "Enter another value for the search (use a negative value to quit): "; cin >> valueToFind; } cout << endl << endl; return;}

Page 20: Program Memory Allocation

Carrano - Chapter 2 CS 150 20

Binary Search (Continued)//////////////////////////////////////////////////////////// Function generateList fills an integer array with //// values in such a way that the array element at index //// i will contain some value between 10*i and 10*i+9. ////////////////////////////////////////////////////////////void generateList(int list[]){ for (int i = 0; i < LIST_SIZE; i++) list[i] = i*10 + randomValue(0,9); return;}

//////////////////////////////////////////////////////////////// Function randomValue generates a pseudorandom integer in //// the range between lowerBound and upperBound (inclusive). ////////////////////////////////////////////////////////////////int randomValue(int lowerBound, int upperBound){ static boolean firstTimeHere = TRUE; long int randomNumberSeed; if (firstTimeHere) { // The first time this function is called, time(&randomNumberSeed); // use the current system time to seed the srand(randomNumberSeed); // random number generator, avoiding identical firstTimeHere = FALSE; // results each time the program is run. } return int((upperBound-lowerBound+1)*(float(rand())/HI_RAND_INT) + lowerBound);}

Page 21: Program Memory Allocation

Carrano - Chapter 2 CS 150 21

Binary Search (Continued)

//////////////////////////////////////////////////////////////////////// Function binSearch recursively examines the integer array list //// (assumed to already be sorted) for soughtValue. If it finds it, //// it places the index of its location in the array in parameter //// correctIndex and terminates. The only other termination //// condition occurs when the search is completely unsuccessful. ////////////////////////////////////////////////////////////////////////boolean binSearch(const int list[], int firstIndex, int lastIndex, int soughtValue, int &correctIndex){ int middleIndex = (firstIndex + lastIndex) / 2; if (lastIndex < firstIndex) return FALSE; else if (list[middleIndex] == soughtValue) { correctIndex = middleIndex; return TRUE; } else if (list[middleIndex] < soughtValue) return binSearch(list, middleIndex+1, lastIndex, soughtValue, correctIndex); else return binSearch(list, firstIndex, middleIndex-1, soughtValue, correctIndex);}

Page 22: Program Memory Allocation

Carrano - Chapter 2 CS 150 22

Binary Search (Continued)

Page 23: Program Memory Allocation

Carrano - Chapter 2 CS 150 23

Recursion Example #6: Maze Solving///////////////////////////////////////////////////////////////////////////////// This program uses recursion to traverse a maze in the form of a character //// matrix, finding the path through the maze, and marking it with asterisks. /////////////////////////////////////////////////////////////////////////////////#include <iostream>#include <fstream>#include "boolean.h"

using namespace std;

const int MATRIX_SIDE = 21;

enum direction {north, east, south, west};

void getMaze(char matrix[MATRIX_SIDE][MATRIX_SIDE], int &startRow, int &startCol, int &destRow, int &destCol);void solveMaze(char matrix[MATRIX_SIDE][MATRIX_SIDE], int startRow, int startCol, int destRow, int destCol);boolean proceed(char matrix[MATRIX_SIDE][MATRIX_SIDE], direction startDirection, int startRow, int startCol, int destRow, int destCol);void printMatrix(char matrix[MATRIX_SIDE][MATRIX_SIDE]);

// Function main retrieves, solves, outputs the maze. //void main(){ char matrix[MATRIX_SIDE][MATRIX_SIDE]; int startRow, startCol; int destRow, destCol; getMaze(matrix,startRow, startCol, destRow,destCol); solveMaze(matrix,startRow,startCol,destRow,destCol); printMatrix(matrix);}

Page 24: Program Memory Allocation

Carrano - Chapter 2 CS 150 24

Maze Solving (Continued)

/////////////////////////////////////////////////////////////////////////////////// Function getMaze retrieves the maze matrix from a specific input file, //// assuming that it is size MATRIX_SIDE x MATRIX_SIDE, and that it is stored //// as MATRIX_SIDE lines of MATRIX_SIDE characters. The four function //// parameters will be assigned the row and column numbers of the entrance and //// exit to the maze (assuming that the entrance is either on the left side or //// the top of the matrix, and the exit is on the side opposite the entrance). ///////////////////////////////////////////////////////////////////////////////////void getMaze(char matrix[MATRIX_SIDE][MATRIX_SIDE], int &startRow, int &startCol, int &destRow, int &destCol){ int i, j; ifstream sourceFile; char nextChar;

sourceFile.open("C:\\TEMP\\maze");

for (i = 0; i < MATRIX_SIDE; i++) { for (j = 0; j < MATRIX_SIDE; j++) { sourceFile.get(nextChar); while (nextChar == '\n') sourceFile.get(nextChar); matrix[i][j] = nextChar; } }

Page 25: Program Memory Allocation

Carrano - Chapter 2 CS 150 25

Maze Solving (Continued) for (i = 1; i < MATRIX_SIDE-1; i++) { if (matrix[i][0] == ' ') { startRow = i; startCol = 0; } else if (matrix[0][i] == ' ') { startRow = 0; startCol = i; }

if (matrix[i][MATRIX_SIDE-1] == ' ') { destRow = i; destCol = MATRIX_SIDE-1; } else if (matrix[MATRIX_SIDE-1][i] == ' ') { destRow = MATRIX_SIDE-1; destCol = i; } } return;}

Page 26: Program Memory Allocation

Carrano - Chapter 2 CS 150 26

Maze Solving (Continued)//////////////////////////////////////////////////////////////////////////////////// Function solveMaze kicks off the recursion which will find (and mark) a path //// through the maze. ////////////////////////////////////////////////////////////////////////////////////void solveMaze(char matrix[MATRIX_SIDE][MATRIX_SIDE], int startRow, int startCol, int destRow, int destCol){ if (startRow == 0) proceed(matrix,east,startRow,startCol,destRow,destCol); else proceed(matrix,south,startRow,startCol,destRow,destCol);}

//////////////////////////////////////////////////////////////////////////////////// Function proceed recursively proceeds through the maze, trying to ascertain //// the path to the exit. Parameter startDirection retains the direction from //// which the current path most recently arose, in order to ensure that no //// attempt will be made to bounce back and forth between two previously visited //// locations. ////////////////////////////////////////////////////////////////////////////////////boolean proceed(char matrix[MATRIX_SIDE][MATRIX_SIDE], direction startDirection, int startRow, int startCol, int destRow, int destCol){ int eastPos[2]; int westPos[2]; int northPos[2]; int southPos[2]; boolean flag = FALSE;

Page 27: Program Memory Allocation

Carrano - Chapter 2 CS 150 27

Maze Solving (Continued) if ((startRow == destRow) && (startCol == destCol)) // TERMINATION CONDITION: flag = TRUE; // DESTINATION REACHED!

else if (matrix[startRow][startCol] != ' ') // TERMINATION CONDITION: flag = FALSE; // DEAD END REACHED!!

else // RECURSIVE CONTINUATION { eastPos[0] = startRow; eastPos[1] = startCol + 1; westPos[0] = startRow; westPos[1] = startCol - 1; northPos[0] = startRow - 1; northPos[1] = startCol; southPos[0] = startRow + 1; southPos[1] = startCol;

switch (startDirection) { case north: { flag = (proceed(matrix,east,eastPos[0],eastPos[1],destRow,destCol) || proceed(matrix,north,northPos[0],northPos[1],destRow,destCol) || proceed(matrix,west,westPos[0],westPos[1],destRow,destCol)); break; } case south: { flag = (proceed(matrix,east,eastPos[0],eastPos[1],destRow,destCol) || proceed(matrix,south,southPos[0],southPos[1],destRow,destCol) || proceed(matrix,west,westPos[0],westPos[1],destRow,destCol)); break; }

Page 28: Program Memory Allocation

Carrano - Chapter 2 CS 150 28

Maze Solving (Continued)

case east: { flag = (proceed(matrix,east,eastPos[0],eastPos[1],destRow,destCol) || proceed(matrix,north,northPos[0],northPos[1],destRow,destCol) || proceed(matrix,south,southPos[0],southPos[1],destRow,destCol)); break; } default: { flag = (proceed(matrix,south,southPos[0],southPos[1],destRow,destCol) || proceed(matrix,north,northPos[0],northPos[1],destRow,destCol) || proceed(matrix,west,westPos[0],westPos[1],destRow,destCol)); break; } } }

// If flag is true, then the destination WAS // // reached via the current "start" position. // if (flag) matrix[startRow][startCol] = '*'; return flag;}

Page 29: Program Memory Allocation

Carrano - Chapter 2 CS 150 29

Maze Solving (Continued)

/////////////////////////////////////////////////////////// Function printMatrix outputs the entire maze matrix.///////////////////////////////////////////////////////////void printMatrix(char matrix[MATRIX_SIDE][MATRIX_SIDE]){ for (int row = 0; row < MATRIX_SIDE; row++) { for (int col = 0; col < MATRIX_SIDE; col++) cout << matrix[row][col]; cout << endl; } cout << endl; return;}

Page 30: Program Memory Allocation

Carrano - Chapter 2 CS 150 30

Maze Solving (Continued)

Sample maze(in file C:\TEMP\maze):+-+-+-+-+-+-+-+-+-+-+| | | | | |+ +-+-+ + + + +-+ + +| | | | | + +-+ + +-+-+-+-+-+-+| |+-+-+ +-+-+-+-+-+-+ +| | | | |+ +-+ +-+-+ + + +-+-+| | | | | |+-+ +-+-+ +-+-+ +-+-+| | | | | | |+ + + +-+-+ + + +-+ +| | | |+-+-+-+-+ +-+-+ +-+-+| | | | | |+ + +-+ +-+ + + + +-+| | | | |+ +-+ + +-+ + +-+ + + | | | | | |+-+-+-+-+-+-+-+-+-+-+

Results of running programon sample maze:

Page 31: Program Memory Allocation

Carrano - Chapter 2 CS 150 31

Recursion vs. Iteration

Note that in several of our examples, it would have been just as easy to implement the algorithms via iteration (i.e., looping) as it was to implement them with recursion.

In fact, the use of recursion for these examples is rather wasteful, forcing the operating system to do extra work and taking the risk that a stack overflow will occur.

When To Use Recursion Instead Of Iteration

When a straightforward iterativesolution cannot be found.

Page 32: Program Memory Allocation

Carrano - Chapter 2 CS 150 32

The Inefficiency of Recursion

One of the big drawbacks to using recursion is the inherent inefficiency of many recursive algorithms. For instance, our maze solving routine frequently revisits coordinates that have already been determined to be dead ends!

On the other hand, some recursive algorithms (e.g., binary search) are vast improvements over alternative solutions.

How To Measure The Efficiency

Of A Recursive Algorithm

Study Math 224 real hard,and then take CS 240 and 340!