# Errata for Mastering Algorithms with C

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date Submitted Date Corrected
Printed
Page xv

Anonymous    Jun 01, 2000
Printed
Page xii
2.4:

"first-in, last-out" (at end of line) now reads "first-in, first-out."

Anonymous    Mar 01, 2001
Printed
Page xiv
Under second item in "About the Code"

"Linux 5.1" now reads "RedHat Linux 5.1."

Anonymous    Mar 01, 2001
Printed
Page 13

Beginning with the third to last line on the page, it did read: "Thus, it remains valid even after f returns...The parameter iptr... so that when f returns..." Now reads: "Thus, it remains valid even after g returns...The parameter iptr... so that when g returns..."

Anonymous    Jun 01, 2000
Printed
Page 17
Figure 2-3, line at bottom

"char b[20]" now reads "char b[20];".

Anonymous    Mar 01, 2001
Printed
Page 22

At the bottom of the page, the last line of code did read: retval = list_ins_next(... Now reads: retval = list_rem_next(...

Anonymous    Jun 01, 2000
Printed
Page 27
The sentence

Think of the fragile leaf of a fern...smaller copy of the overall leaf; or the repeating patterns in a reflection... NOW READS: Think of the fragile leaf of a fern...smaller copy of the overall leaf. Think of the repeating patterns in a reflection...

Anonymous    Dec 01, 2003
Printed
Page 34

The equation at the bottom of the page did read: T(n) = 1 if n = 0 2T(n/2) + n if n > 0 Now reads: T(n) = 1 if n = 2 2T(n/2) + n if n = 1, n > 2

Anonymous    Jun 01, 2000
Printed
Page 36

Previously read "... the frame pointer, keeps track of the top of the stack as a program exicutes. It is also used to determine when the stack has grown too large. An interrupt is raised to signal the error. NOW READS: " ... the frame pointer addresses the top frame on the stack. It's the stack pointer that points to the actual top of the stack (that is, the point where the next stack frame will be pushed). Therefore, although a system could use the frame pointer to determine stack overflow, it probably is the stack pointer that would normally be used."

Anonymous    Dec 01, 2003
Printed
Page 49
Part II, line 5

"first-in, last-out" (at beginning of line) now reads "first-in, first-out."

Anonymous    Mar 01, 2001
Printed
Page 52
first words under "Description of Linked Lists:"

"Singly-linked lists..." wrongly HAD an extra space and an "s" in italics. This has been corrected.

Anonymous    Dec 01, 2003
Printed
Page 64

Line 5 from top did read: if (list_size(list) == 0) Now reads: if (list_size(list) == 1)

Anonymous    Jun 01, 2000
Printed
Page 91
At the top of the page, the lines

old_element = element->next; element->next = element->next->next; ARE NOW FOLLOWED by the two additional lines: if (old_element == clist_head(list)) list->head = old_element->next;

Anonymous    Dec 01, 2003
Printed
Page 99

Remove the text " in real time" under the item "X Window System".

Anonymous    May 01, 2008
Other Digital Version
99

Remove the text " in real time" under the item "X Window System".

Anonymous    May 01, 2008
Printed
Page 133
The 2nd-to-last sentence of the second paragraph under "Set Example: Set

Covering" now reads: The various player skill sets in P that are placed in set C together must cover all of the skills in set S.

Anonymous    Mar 01, 2001
Printed
Page 146-147

All occurrences of "int" in the implementation of hashpjw HAVE BEEN CHANGED to "unsigned int".

Anonymous    Dec 01, 2003
Printed
Page 162
In the table at the top of the page, the first line in the second column

1 / (1 - 0.50) < 2 now reas: < 1 / (1 - 0.50) = 2

Anonymous    Mar 01, 2001
Printed
Page 181

The definition for "Preorder traversal" has been changed to read: "In a preorder traversal for a given subtree, we first traverse its root, then to the left, and then to the right. As we explore subtrees to the left and right, we proceed in a similar manner using the left or right node as the root of the new subtree. The preorder traversal is a depth-first exploration, like that presented for graphs in Chapter 11, Graphs."

Anonymous    Jun 01, 2000
Printed
Page 182

The definition for "Inorder traversal" has been changed to read: "In an inorder traversal for a given subtree, we first traverse to the left, then to the root, and then to the right. As we explore subtrees to the left and right, we proceed in a similar manner using the left or right node as the root of the new subtree."

Anonymous    Jun 01, 2000
Printed
Page 182

The definition for "Postorder traversal" has been changed to read: "In a postorder traversal for a given subtree, we first traverse to the left, then to the right, and then to the root. As we explore subtrees to the left and right, we proceed in a similar manner using the left or right node as the root of the new subtree."

Anonymous    Jun 01, 2000
Printed
Page 190
section on bitree_merge

2nd line says "... by calling bitree_merge." This now reads "...by calling bitree_init."

Anonymous    Mar 01, 2001
Printed
Page 205
Under the section "bitree_remove", "Furthermore," HAS BEEN DELETED from

the second-to-last sentence.

Anonymous    Dec 01, 2003
Printed
Page 207

Change the value inside the circle to the far right from 81 to 83.

Anonymous    May 01, 2008
Other Digital Version
207

Change the value inside the circle to the far right from 81 to 83.

Anonymous    May 01, 2008
Printed
Page 215

A line of code has been added at the end of the page to read: static void destroy_right(BisTree *tree, BiTreeNode *node);

Anonymous    Jun 01, 2000
Printed
Page 219

In the function destroy_left, the calls did read: bitree_rem_left(tree, *position); bitree_rem_right(tree, *position); Now read: destroy_left(tree, *position); destroy_right(tree, *position);

Anonymous    Jun 01, 2000
Printed
Page 269
top of the page

It is the responsibility of the caller to manage the storage associated with data2. "data2" is now in ConstantWidth italics font.

Anonymous    Mar 01, 2001
Printed
Page 277
Example 11-2, last line on page

Anonymous    Mar 01, 2001
Printed
Page 277
last line on the page

The line that reads: set_init(&adjlist->adjacent, graph->match, graph->destroy); NOW READS: set_init(&adjlist->adjacent, graph->match, NULL); **AUTHOR'S RESPONSE It is important to note that when inserting an edge into a graph, the data2 parameter of graph_ins_edge must have *its own* storage allocated for it. For example, data2 cannot share storage with a vertex passed to graph_ins_vertex at some earlier time. For example, to create the graph below, we should do something like the following: Graph: --------- a -> b b --------- data2 = (char *)malloc(2); strcpy(data2, "b"); graph_ins_vertex(&graph, data2); data1 = (char *)malloc(2); strcpy(data1, "a"); graph_ins_vertex(&graph, data1); data2 = (char *)malloc(2); strcpy(data2, "b"); graph_ins_edge(&graph, data1, data2); Note that before the call to graph_ins_edge, we allocate new storage for data2. This is because inside of graph_ins_vertex, set_init initializes each new adjacency list with graph->destroy, which will be called once for each vertex in the adjacency list when the graph is destroyed. Since every vertex also appears in the list of AdjList structures, without its own storage each vertex will be destroyed more than once. One solution is to set the destroy parameter of set_init to NULL. However, this alternative poses problems in the form of consistency issues. The important thing to remember, therefore, is simply this: Before any piece of data is inserted into a data structure, it must have *its own* storage allocated for it. (Notice that it is perfectly acceptable in the call to graph_ins_edge, however, not to allocate new storage for data1 because data1 is used only to look up in which adjacency list data2 will be inserted; in other words, the graph does not have a pointer to data1 once the operation completes.

Anonymous    Aug 01, 2005
Printed
Page 290
There is an erroneous comma in the middle of the return statement.

Anonymous    Dec 01, 2003
Printed
Page 291

Change "acrylic" to "acyclic".

Anonymous    May 01, 2008
Other Digital Version
291

Change "acrylic" to "acyclic".

Anonymous    May 01, 2008
Printed
Page 304
In the second paragraph under the section on implementation and

analysis, the third sentence did read: "Since the element at the left of the sorted set..." Now reads: "Since the element just to the right of the sorted set..."

Anonymous    Jun 01, 2000
Printed
Page 323

In Example 12.5, change the line of code: int mgsort(void *data, int size, int esize, int i, ... to: int mgsort(void *data, int esize, int i, ... That is, remove "int size, " since this parameter is not used. We should also make sure that this is changed in the code on disk.

Anonymous    May 01, 2008
Other Digital Version
323

In Example 12.5, change the line of code: int mgsort(void *data, int size, int esize, int i, ... to: int mgsort(void *data, int esize, int i, ... That is, remove "int size, " since this parameter is not used. We should also make sure that this is changed in the code on disk.

Anonymous    May 01, 2008
Printed
Page 325

The second sentence in the "Description" section did read: "The argument k specifies the maximum integer in data." Now reads: "The argument k specifies the maximum integer in data, plus 1."

Anonymous    Jun 01, 2000
Printed
Page 325

The sentence in the "Complexity" section did read: "...the maximum integer in the unsorted set." Now reads: "...the maximum integer in the unsorted set, plus 1."

Anonymous    Jun 01, 2000
Printed
Page 325

The first sentence in the last paragraph on the page did read: "...the largest integer being sorted." Now reads: "...the largest integer being sorted, plus 1."

Anonymous    Jun 01, 2000
Printed
Page 327
If the allocation of storage for the sorted elements fails, we should

free the storage just allocated for the counts before returning. Thus, the lines: if ((temp = (int *)malloc(size * sizeof(int))) == NULL) return -1; should read: if ((temp = (int *)malloc(size * sizeof(int))) == NULL) { free(counts); return -1; }

Anonymous    Dec 01, 2003
Printed
Page 345

The values in the first three columns for i=4 in Figure 13.1 should be 4, 0.0, 0.5. That is, changed the value in the third column of this row, 1.5, to 0.5.

Anonymous    May 01, 2008
Other Digital Version
345

The values in the first three columns for i=4 in Figure 13.1 should be 4, 0.0, 0.5. That is, changed the value in the third column of this row, 1.5, to 0.5.

Anonymous    May 01, 2008
Printed
Page 346
2.1:

"i < k" now reads "i < j".

Anonymous    Mar 01, 2001
Printed
Page 363
Under "Related Topics", another related topic HAS BEEN ADDED before

"Error Approximation". The new topic READS AS FOLLOWS: Numerical Representation in Computers The representation of numbers in computers is finite. Consequently, computers are limited in the way they can work with certain types of numbers, such as those that are extremely small or large. An understanding of these limitations is important before undertaking most serious work in numerical analysis. This chapter assumes an understanding of these limitations.

Anonymous    Aug 01, 2005
Printed
Page 374
The ninth line down of code did read:

for (i = 0; i < (size / 8); i++) { Now reads: for (i = 0; i <= ((size - 1) / 8); i++) {

Anonymous    Jun 01, 2000
Printed
Page 451
The second sentence in the fourth paragraph on the page has been

changed to read: "To do this, we must ensure that the largest value that the block can store, considering its total number of bits, is less than n."

Anonymous    Jun 01, 2000
Printed
Page 503
middle of page, after the sentence

The straddle test determines the orientation of p3 relative to p2 and of p4 relative to p2 with respect to p1. The following HAS BEEN ADDED: It then determines the orientation of [p1] relative to [p4] and of [p2] relative to [p4] with respect to [p3]. Note that [ ] above indicates an item in constant width italic font. ALSO the sentence that begins: If the orientations are different, or if either orientation is 0... NOW READS: If the orientations of the points in either computation are different or 0, the straddle test succeeds, and the algorithm returns that the line segments intersect; otherwise, the line segments do not intersect.

Anonymous    Aug 01, 2005
Printed
Page 503-504

Code should be this: /***************************************************************************** * * * -------------------------------- lint.c ------------------------------- * * * *****************************************************************************/ #include "geometry.h" /***************************************************************************** * * * --------------------------------- lint --------------------------------- * * * *****************************************************************************/ int lint(Point p1, Point p2, Point p3, Point p4) { double z1, z2, z3, z4; int s1, s2, s3, s4; /***************************************************************************** * * * Perform the quick rejection test. * * * *****************************************************************************/ if (!(MAX(p1.x, p2.x) >= MIN(p3.x, p4.x) && MAX(p3.x, p4.x) >= MIN(p1.x, p2.x) && MAX(p1.y, p2.y) >= MIN(p3.y, p4.y) && MAX(p3.y, p4.y) >= MIN(p1.y, p2.y))) { { return 0; } /***************************************************************************** * * * Determine whether the line segments straddle each other. * * * *****************************************************************************/ if ((z1 = ((p3.x - p1.x)*(p2.y - p1.y)) - ((p3.y - p1.y)*(p2.x - p1.x))) < 0) s1 = -1; else if (z1 > 0) s1 = 1; else s1 = 0; if ((z2 = ((p4.x - p1.x)*(p2.y - p1.y)) - ((p4.y - p1.y)*(p2.x - p1.x))) < 0) s2 = -1; else if (z2 > 0) s2 = 1; else s2 = 0; if ((z3 = ((p1.x - p3.x)*(p4.y - p3.y)) - ((p1.y - p3.y)*(p4.x - p3.x))) < 0) s3 = -1; else if (z3 > 0) s3 = 1; else s3 = 0; if ((z4 = ((p2.x - p3.x)*(p4.y - p3.y)) - ((p2.y - p3.y)*(p4.x - p3.x))) < 0) s4 = -1; else if (z4 > 0) s4 = 1; else s4 = 0; if ((s1 * s2 <= 0) && (s3 * s4 <= 0)) return 1; /***************************************************************************** * * * Return that the line segments do not intersect. * * * *****************************************************************************/ return 0; }

Anonymous    May 01, 2008
Other Digital Version
503-504

Code should be this: /***************************************************************************** * * * -------------------------------- lint.c ------------------------------- * * * *****************************************************************************/ #include "geometry.h" /***************************************************************************** * * * --------------------------------- lint --------------------------------- * * * *****************************************************************************/ int lint(Point p1, Point p2, Point p3, Point p4) { double z1, z2, z3, z4; int s1, s2, s3, s4; /***************************************************************************** * * * Perform the quick rejection test. * * * *****************************************************************************/ if (!(MAX(p1.x, p2.x) >= MIN(p3.x, p4.x) && MAX(p3.x, p4.x) >= MIN(p1.x, p2.x) && MAX(p1.y, p2.y) >= MIN(p3.y, p4.y) && MAX(p3.y, p4.y) >= MIN(p1.y, p2.y))) { { return 0; } /***************************************************************************** * * * Determine whether the line segments straddle each other. * * * *****************************************************************************/ if ((z1 = ((p3.x - p1.x)*(p2.y - p1.y)) - ((p3.y - p1.y)*(p2.x - p1.x))) < 0) s1 = -1; else if (z1 > 0) s1 = 1; else s1 = 0; if ((z2 = ((p4.x - p1.x)*(p2.y - p1.y)) - ((p4.y - p1.y)*(p2.x - p1.x))) < 0) s2 = -1; else if (z2 > 0) s2 = 1; else s2 = 0; if ((z3 = ((p1.x - p3.x)*(p4.y - p3.y)) - ((p1.y - p3.y)*(p4.x - p3.x))) < 0) s3 = -1; else if (z3 > 0) s3 = 1; else s3 = 0; if ((z4 = ((p2.x - p3.x)*(p4.y - p3.y)) - ((p2.y - p3.y)*(p4.x - p3.x))) < 0) s4 = -1; else if (z4 > 0) s4 = 1; else s4 = 0; if ((s1 * s2 <= 0) && (s3 * s4 <= 0)) return 1; /***************************************************************************** * * * Return that the line segments do not intersect. * * * *****************************************************************************/ return 0; }

Anonymous    May 01, 2008