Welcome to Scribd, the world's digital library. Read, publish, and share books and documents. See more
Download
Standard view
Full view
of .
Look up keyword
Like this
1Activity
0 of .
Results for:
No results containing your search query
P. 1
h25s section solutions 4

h25s section solutions 4

Ratings: (0)|Views: 5|Likes:
Published by minhhai2209

More info:

Published by: minhhai2209 on Feb 18, 2009
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

02/01/2013

pdf

text

original

CS106B
Handout #24S
Yves Lu
July 23, 2008
Section Solutions #4
Problem 1: Append

/**
* Function: Append
* Usage: Append(first, second)

*----------------------------

* The following function appends the second linked list on
* to the end of the first.
*/
void Append(Node *& first, Node* second)
{

if (first == NULL)
{
first = second;
}else
{
Append(first->next, second);
}
}Note that the first parameter to the function is a reference. In the function, we are assigning
first = second. For this change to be seen by the caller, firstneeds to be passed by
reference. One way that many programmers try to get around this is by changing the function to
the following:
void IncorrectAppend(Node *first, Node* second)

{
if (first->next == NULL)
{

first->next = second;
}else
{
IncorrectAppend(first->next, second);
}
}Because now the assignment is dereferencing a pointer, the change will be seen by the caller.
The one problem here is what happens when first is a completely empty list. Because first is
NULL, first has no next, so we\u2019ll crash if we try to dereference it. This is why the first version is
correct and the second is not.

To show why the first one will work, here is a diagram showing what happens when you have an empty list passed toAppend. This first picture is whenAppend has first been called but has not executed. Note howfirst is a reference to the list in main.

2
int main()

{
Node *list = NULL;
Node *toAppend = new Node;
toAppend->next = NULL;
Append(list, toAppend);

}Now look at what happens after we make the assignment first = second. Becausefirst is a
reference tolist, the change is seen inmain!
Append
main
first
second
list
toAppend
Append
main
first
second
list
toAppend
3
Problem 2: Linked List Trace

The functionPopRocks takes the cell in the list that the parameter points to, removes that cell
from its current position in the list, and tacks it on the end of the list. Therefore, if the parameter
is a pointer to the first element in the list, the lists would end up looking like this:

30 -> 45 -> 60 -> 15
't' -> 'a' -> 'r' -> 's'
"hang" -> "a" -> "salami," -> "I'm" -> "a" -> "lasagna" -> "hog!" -> "Go"

Problem 3: Big-O
a)Binkyis O(lg N). The loop iterates until either aor bis\u2264 0 or until both are exactly 1. a

starts at N and is halved each time, so it requires ~lg N iterations to reach 1 and one more to
reach 0.b starts at N/2 and is decremented by one each time, so it takes ~N/2 steps to become 1
and one more to reach 0.a will reach 0 first, taking lg N steps, soBinky has O(lg N)
performance overall.

b)Winkyis O(2N). A call to Winkyturns into a call to Pinkyon N. Each call to Pinkymakes

two recursive calls that are each one smaller. This is the same as Towers of Hanoi or knapsack. You might recognize the classic 2N pattern or get the result by solving the recurrence relation of T(N) = 2*T(N-1) + 1 or drawing the recursion tree and counting the number of calls.

Problem 4: Big-O Analysis

To find all the words one letter away from a target by changing one letter and then doing a
lexicon look up takes time O(k log N). If the length of the target word is k, then it takes time
O(25 * k) = O(k) to generate all of the candidate words. This is because we change one letter at a
time and have 25 possible choices of what we could change it to per letter. Then, since we
assume word lookup in the lexicon is done with a binary search, it takes time O(log N) to see if a
word is in the lexicon, where N is the size of the lexicon. Thus, our total time is O(k log N) to
use this first algorithm.

If instead we iterate through the entire lexicon, then our total runtime is O(k * N). This is
because if there are N words in the dictionary then it takes time O(N) to iterate through it. Then,
if our target word has length k, then to see if a given word is one character away takes time O(k),
since we possibly have to iterate over the entire target string. Thus the total runtime is O(k * N).

From the Big-O analysis, it would appear the first method would always be better. However, in the first algorithm our O(k) is more expensive than in the second, since we have to generate 25 * k candidate strings. For a smaller lexicon then it may be more beneficial to do the second

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->