Assignment 6: Complexity Analysis

This assignment is due at midnight on Wednesday, March 10th, 2004 (i.e., the moment Thursday starts). The assignment is a written one, and must be submitted as a single file, a README. Refer to the homework policies page for general homework guidelines.

This assignment will give you practice analyzing the running time of algorithms.

When answering the following questions, explain clearly why your answer is correct, and show work for significant intermediate steps of computations. For example, when analyzing the running time of a code fragment, include the running time for each individual line.

Normally, it is sufficient to provide an asymptotic (big-O) analysis. Exceptions would include where the problem statement indicates otherwise, or when you believe that constants and low-order terms have a significant impact on the answer.

The code fragments are only fragments, and they may ignore certain niceties of C++ style. Don't pick at the details. Treat them as particularly explicit pseudo-code.

Even though there is no supplied code, and in fact no code at all, for
this assignment, you still need to use `cs70checkout hw06`

to create your homework directory; otherwise submission won't work.
Put your solutions in a text file named README and submit this file
using `cs70submit`

. Your file must be a **PLAIN TEXT**
file. Do not submit
(for example) a postscript file, a Word document, or an HTML file.
Represent your equations using notation similar to the following
examples:

O(N) O(N log N) O(N^2)

Provide a big-O analysis of the running times for the code fragments
given in Weiss, problem 6.15. (Do part "a" only.)
You may assume that `sum`

was declared as:

int sum = 0;before each code fragment. Give your analysis in terms of the loop limit variable,

`n`

.
Provide a big-O analysis of the running time for the code fragment
given in Weiss, problem 6.16. (Again, do only part "a".)
You may assume that `sum`

was declared as:

int sum = 0;before the code fragment. Give your analysis in terms of the loop limit variable,

`n`

.
Suppose that we define a linked list class with the following data fields.

class Node { friend class List; private: long value; Node *next; }; class List { private: Node *head; };

How long (in big-O terms) do the following operations take, as a
function of the length
of the list, N? You may not assume any changes in the
`Node`

or `List`

data structures. For this
problem and the next, assume that any single call to `new`

,
`new[]`

, `delete`

, or `delete[]`

can
be performed in O(1) time.

- Making a copy of the list
- Adding a value to the start of the list
- Adding a value to the end of the list
- Removing the first value from the list
- Removing the last value from the list
- Determining whether the list contains some value V

Suppose that we modify the classes from Problem 3 to store C++
`string`

s of maximum length M characters,
rather than `long`

s. Does
this affect the running
of any of the
operations? If so, which one(s) change, why, and what is/are the new
expression(s) for the running time(s)?

Notice that each list should contain **its own private copy** of
the strings stored in it. Lists should not share strings with other
lists, or with other parts of the code.

You should assume that when a string is copied or assigned, a complete
copy is made of that string. (Interestingly, this assumption is not
true for all implementations of the C++ library, but we'll ignore that
fact for this assignment.)
You should also assume that the `string`

type has been
implemented in an efficient and effective fashion (i.e., there are no
O(N^2) implementations of things that can be done in O(N) time).

Consider the following functions, which use the `List`

and
`Node`

data structures from Problem 3:

// returns the length of the list int List::length() { Node *current = head; int output = 0; while (current != NULL) { output++; current = current->next; } return output; } // returns the nth value in the list long List::nth(int n) { if (n >= length() || n < 0) error("List::nth out of range position"); Node *current = head; for (i = 0; i < n; i++) { current = current->next; } return current->value; } // prints all the values in the list void List::print() { for (i = 0; i < length(); i++) { cout << nth(i) << endl; } }

Analyze the running times of these three functions. For each
function, show how it could be recoded (if possible) so as to improve
its asymptotic running time, and provide an analysis of the new
running time. If no improvement is possible, explain why. You are
only allowed to modify the executable code; you may not modify or add
any fields to the `Node`

and `List`

data
structures.

*© 2004, Geoff Kuenning*

This page is maintained by Geoff Kuenning.