Errata

Mastering Algorithms with C

Errata for Mastering Algorithms with C

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
ePub Page Section 12.6 - Implementation and analysis of Quicksort
Example 12.2 code listing, vs description in paragraph 5 of Section 12.4 - Description of Quicksort

I have a question about the implementation of the "median of three" method in the partition function for quicksort in this book (section 12.6 - Implementation and Analysis of Quicksort). It doesn't seem to follow from the explanation in the text.

In the text (paragraph 5 & 6 of Section 12.4 - Description of Quicksort) a randomized median of three method is described and makes sense to me. You pick 3 random values from the array to be sorted, choose their median value (by sorting those 3 elements and picking the middle one), and pivot around that. However, in the implementation, it looks like the median of the indices is being taken, rather than the median of the values at those indices. My understanding was that the aim would be to get the median of the values, and not the indices, in order to find a partition value that partitions the array as evenly as possible to get nlogn performance.

Here's a snippet with the relevant code

static int partition(void *data, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)
char *a = data;
void *pval;
void *temp;
int r[3];

if ((pval = malloc(esize)) == NULL) {
return -1;
}
if ((temp = malloc(esize)) == NULL) {
free(pval);
return -1;
}

r[0] = (rand() % (k - i + 1)) + i;
r[1] = (rand() % (k - i + 1)) + i;
r[2] = (rand() % (k - i + 1)) + i;

issort(r, 3, sizeof(int), compare_int); // sorting indices instead of values..???
memcpy(pval, &a[r[1] * esize], esize);

Jamie O'Sullivan  Feb 15, 2023 
5.5.1
Code example 5.5.1 function dlist_remove

function implementation
int dlist_remove(DList *list, DListElmt *element, void **data)

contains an error that leads to a memory leak. The function receives **data
as a parameter but it does not free data. Also, pass data as a parameter is not
necessary because *element contains a pointer to data.

A possible fix could be

/* Remove the element from the list */
*data = element->data; //this is the original code

if(list->destroy != NULL) {
//call user defined function to free allocated data
list->destroy(data);
}
else {
free(data);
}

This change would affect also to function dlist_destroy
If this change is accepted then in dlist_destroy is not necessary to call
list->destroy()

Julio Osvaldo Angulo Salinas  Apr 25, 2019 
Printed Page 28
Middle of page.

The sentence:
"If we then think of (n-1)! as n-1 times (n-2)!, (n-2)! as n-2 times (n-3)!, and so forth until n=1, we end up computing n!."


In the above, n does not change, it should be something like:
"until (n-k) = 1, where k is the index from 1 to n-1."

n! = (n)(n-1)(n-2)...(n-k)

Tom Clark  Mar 13, 2013 
PDF Page 129
1st line

The following line of code in the book:
set_init(setu, set1->match, NULL);

should be:
set_init(setu, set1->match, free);

otherwise the following line of code won't work:
set_destroy(setu);

Anonymous  Oct 19, 2015 
ePub, Mobi Page 155

4.5 Questions and Answers

Q: … O(n^2), O(3^n), O(2^n) …
A: … O(2^n), O(3n), O(n!) …

should be

Q: … O(n^2), O(3^n), O(2^n) …
A: … O(2^n), O(3^n), O(n!) …

kamimura  Jun 15, 2015 
Printed Page 214
Figure 9-13

Balance factor for node labeled 45 in step 1 should be +1, not -1. Balance factor for node labeled 20 in step 4 should be 0, not +1.

Dan Brace  Jun 27, 2015 
PDF Page 341
first paragraph

Line states "Had we used a radix of 2**8, radix sort
would have required O(pn + pk) = (16)(2**8) + (16)(2**8) = 8160"

1)First, (16 * (2 ** 8)) + (16 * (2 ** 8)) = 8192, not 8160
2) In fact, it should be (16 * (2 ** 10)) + (16 * (2 ** 8)) = 20480
Then, we have different conclusion that radix sorting is still slower but much less slower that for radix 2**16.

Anonymous  May 27, 2010 
Printed Page 408
1st paragraph

lz77 compression code contains a few bugs

1. `tbits` is missing its declaration with the other ints.
2. a declaration of `unsigned int token` is also missing.

Further, to make lz77 work, page 411 needs the following line changed :
`tpos = (sizeof(unsigned long) * 8) - tbits + i;`
`tpos = (sizeof(unsigned int) * 8) - tbits + i;`

verified with gcc 9.1.0 (linux) and MSVC 19.14.26433 (Win 10 1903)

Anonymous  Nov 10, 2019 
Printed Page 500
the displayed formula in italics between the 2nd and third paragraph

The general formula for computing the x coordinate of the intersection of two lines is incorrect. Your formula

x_i = (b_line2 - b_line1) / (m_line2 - m_line1)

would result in -x_i, instead of x_i. The correct formula should be

x_i = (b_line2 - b_line1) / (m_line1 - m_line2).


Nicholas Cousar  Sep 10, 2020