Errata

C# 3.0 Cookbook

Errata for C# 3.0 Cookbook

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. 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 432
11.5

There seems to be a couple of errors/omissions in the code. Here is the correct code -

using System;
using System.collections;
using System.collections.Generic;

public class NTree<T>
where T : IComparable<T>
{
public NTree()
{
maxChildren = int.MaxValue;
}

public NTree(int maxNumChildren)
{
maxChildren = maxNumChildren;
}

// The root node of the tree
private NTreeNodeFactory<T>.NTreeNode<T> root = null;
// The maximum number of child nodes that a parent node may contain
private int maxChildren = 0;

public void AddRoot(NTreeNodeFactory<T>.NTreeNode<T> node)
{
root = node;
}

public NTreeNodeFactory<T>.NTreeNode<T> GetRoot()
{
return (root);
}

public int MaxChildren
{
get {return (maxChildren);}
}
}

public class NTreeNodeFactory<T>
where T : IComparable<T>
{
public NTreeNodeFactory(NTree<T> root)
{
maxChildren = root.MaxChildren;
}

private int maxChildren = 0;

public int MaxChildren
{
get {return (maxChildren);}
}

public NTreeNode<T> CreateNode(T value)
{
return (new NTreeNode<T>(value, maxChildren));
}

// Nested Node class
public class NTreeNode<U>
where U : IComparable<U>
{
public NTreeNode(U value, int maxChildren)
{
if (!value.Equals(null))
{
nodeValue = value;
}

childNodes = new NTreeNode<U>[maxChildren];
}

protected U nodeValue = default(U);
protected NTreeNode<U>[] childNodes = null;

public int NumOfChildren
{
get {return (CountChildren());}
}

public int CountChildren()
{
int currCount = 0;

for (int index = 0; index <= childNodes.GetUpperBound(0); index++)
{
if (childNodes[index] != null)
{
++currCount;
currCount += childNodes[index].CountChildren();
}
}

return (currCount);
}

public int CountImmediateChildren()
{
int currCount = 0;

for (int index = 0; index <= childNodes.GetUpperBound(0); index++)
{
if (childNodes[index] != null)
{
++currCount;
}
}

return (currCount);
}

public NTreeNode<U>[] Children
{
get {return (childNodes);}
}

public NTreeNode<U> GetChild(int index)
{
return (childNodes[index]);
}

public U Value()
{
return (nodeValue);
}

public void AddNode(NTreeNode<U> node)
{
int numOfNonNullNodes = CountImmediateChildren();

if (numOfNonNullNodes < childNodes.Length)
{
childNodes[numOfNonNullNodes] = node;
}
else
{
throw (new InvalidOperationException("Cannot add more children to this
node."));
}
}

public NTreeNode<U> DepthFirstSearch(U targetObj)
{
NTreeNode<U> retObj = default(NTreeNode<U>);

if (targetObj.CompareTo(nodeValue) == 0)
{
retObj = this;
}
else
{
for (int index=0; index<=childNodes.GetUpperBound(0); index++)
{
if (childNodes[index] != null)
{
retObj = childNodes[index].DepthFirstSearch(targetObj);
if (retObj != null)
{
break;
}
}
}
}

return (retObj);
}

public NTreeNode<U> BreadthFirstSearch(U targetObj)
{
Queue<NTreeNode<U>> row = new Queue<NTreeNode<U>>();
row.Enqueue(this);

while (row.Count > 0)
{
// Get next node in queue
NTreeNode<U> currentNode = row.Dequeue();

// Is this the node we are looking for?
if (targetObj.CompareTo(currentNode.nodeValue) == 0)
{
return (currentNode);
}

for (int index = 0;
index < currentNode.CountImmediateChildren();
index++)
{
if (currentNode.Children[index] != null)
{
row.Enqueue(currentNode.Children[index]);
}
}
}

return (null);
}

public void PrintDepthFirst()
{
Console.WriteLine("this: " + nodeValue.ToString());

for (int index = 0; index < childNodes.Length; index++)
{
if (childNodes[index] != null)
{
Console.WriteLine(" childNodes[" + index + "]: " +
childNodes[index].nodeValue.ToString());
}
else
{
Console.WriteLine(" childNodes[" + index + "]: NULL");
}
}

for (int index = 0; index < childNodes.Length; index++)
{
if (childNodes[index] != null)
{
childNodes[index].PrintDepthFirst();
}
}
}

public void RemoveNode(int index)
{
// Remove node from array and Compact the array
if (index < childNodes.GetLowerBound(0) ||
index > childNodes.GetUpperBound(0))
{
throw (new ArgumentOutOfRangeException("index", index,
"Array index out of bounds."));
}
else if (index < childNodes.GetUpperBound(0))
{
Array.Copy(childNodes, index + 1, childNodes, index,
childNodes.Length - index - 1);
}

childNodes.SetValue(null, childNodes.GetUpperBound(0));
}
}
}

// TEST CODE:

public static void TestNTree()
{
NTree<string> topLevel = new NTree<string>(3);
NTreeNodeFactory<string> nodeFactory = new
NTreeNodeFactory<string>(topLevel);

NTreeNodeFactory<string>.NTreeNode<string> one =
nodeFactory.CreateNode("One");
NTreeNodeFactory<string>.NTreeNode<string> two =
nodeFactory.CreateNode("Two");
NTreeNodeFactory<string>.NTreeNode<string> three =
nodeFactory.CreateNode("Three");
NTreeNodeFactory<string>.NTreeNode<string> four =
nodeFactory.CreateNode("Four");
NTreeNodeFactory<string>.NTreeNode<string> five =
nodeFactory.CreateNode("Five");
NTreeNodeFactory<string>.NTreeNode<string> six =
nodeFactory.CreateNode("Six");
NTreeNodeFactory<string>.NTreeNode<string> seven =
nodeFactory.CreateNode("Seven");
NTreeNodeFactory<string>.NTreeNode<string> eight =
nodeFactory.CreateNode("Eight");
NTreeNodeFactory<string>.NTreeNode<string> nine =
nodeFactory.CreateNode("Nine");

topLevel.AddRoot(one);
Console.WriteLine("topLevel.GetRoot().CountChildren: " +
topLevel.GetRoot().CountChildren());

topLevel.GetRoot().AddNode(two);
topLevel.GetRoot().AddNode(three);
topLevel.GetRoot().AddNode(four);

topLevel.GetRoot().Children[0].AddNode(five);
topLevel.GetRoot().Children[0].AddNode(eight);
topLevel.GetRoot().Children[0].AddNode(nine);
topLevel.GetRoot().Children[1].AddNode(six);
topLevel.GetRoot().Children[1].Children[0].AddNode(seven);

Console.WriteLine("Display Entire tree:");
topLevel.GetRoot().PrintDepthFirst();

Console.WriteLine("Display tree from node [two]:");
topLevel.GetRoot().Children[0].PrintDepthFirst();

Console.WriteLine("Depth First Search:");
Console.WriteLine("topLevel.DepthFirstSearch(One): " +
topLevel.GetRoot().DepthFirstSearch("One").Value().ToString());
Console.WriteLine("topLevel.DepthFirstSearch(Two): " +
topLevel.GetRoot().DepthFirstSearch("Two").Value().ToString());
Console.WriteLine("topLevel.DepthFirstSearch(Three): " +
topLevel.GetRoot().DepthFirstSearch("Three").Value().ToString());
Console.WriteLine("topLevel.DepthFirstSearch(Four): " +
topLevel.GetRoot().DepthFirstSearch("Four").Value().ToString());
Console.WriteLine("topLevel.DepthFirstSearch(Five): " +
topLevel.GetRoot().DepthFirstSearch("Five").Value().ToString());

Console.WriteLine("

Breadth First Search:");
Console.WriteLine("topLevel.BreadthFirstSearch(One): " +
topLevel.GetRoot().BreadthFirstSearch("One").Value().ToString());
Console.WriteLine("topLevel.BreadthFirstSearch(Two): " +
topLevel.GetRoot().BreadthFirstSearch("Two").Value().ToString());
Console.WriteLine("topLevel.BreadthFirstSearch(Three): " +
topLevel.GetRoot().BreadthFirstSearch("Three").Value().ToString());
Console.WriteLine("topLevel.BreadthFirstSearch(Four): " +
topLevel.GetRoot().BreadthFirstSearch("Four").Value().ToString());
}

Anonymous   
Printed
Page 553
source code at the top of the page

The code "sb.ToString()" should be "stringBuilder.ToString()".

Note from the Author or Editor:
This was actually in the 1st edition of the C# Cookbook which has recipe 11.6 in it and in that edition the line streamWriter.WriteLine(sb.ToString()) should actually be streamWriter.WriteLine(stringBuilder);

Stephen Korow  Mar 08, 2010 
Printed
Page 855
top index entry in left column

index entry "wVisual Studio" should be "Visual Studio" (no "w" at beginning)

Anonymous