面接の質問を1つ解決しようとしていましたが、そのためにはバイナリツリーをレベルごとに移動する必要があります。以下の変数を持つBinaryNodeを設計しました
private object data;
private BinaryNode left;
private BinaryNode right;
誰かが私のBinarySearchTreeクラス内にBreadthFirstSearchメソッドを書くのを手伝ってもらえますか?
更新:ご意見をお寄せいただきありがとうございます。これがインタビューの質問でした。 「バイナリ検索ツリーが与えられた場合、各深さですべてのノードのリンクリストを作成するアルゴリズムを設計します(つまり、深さDのツリーがある場合、Dリンクリストになります)。
これが私の方法です。専門家のコメントを教えてください。
public List<LinkedList<BNode>> FindLevelLinkList(BNode root)
{
Queue<BNode> q = new Queue<BNode>();
// List of all nodes starting from root.
List<BNode> list = new List<BNode>();
q.Enqueue(root);
while (q.Count > 0)
{
BNode current = q.Dequeue();
if (current == null)
continue;
q.Enqueue(current.Left);
q.Enqueue(current.Right);
list.Add(current);
}
// Add tree nodes of same depth into individual LinkedList. Then add all LinkedList into a List
LinkedList<BNode> LL = new LinkedList<BNode>();
List<LinkedList<BNode>> result = new List<LinkedList<BNode>>();
LL.AddLast(root);
int currentDepth = 0;
foreach (BNode node in list)
{
if (node != root)
{
if (node.Depth == currentDepth)
{
LL.AddLast(node);
}
else
{
result.Add(LL);
LL = new LinkedList<BNode>();
LL.AddLast(node);
currentDepth++;
}
}
}
// Add the last linkedlist
result.Add(LL);
return result;
}
通常、幅優先検索はqueueを使用して実装され、深さ優先検索はstackを使用して実装されます。
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
while(q.Count > 0)
{
Node current = q.Dequeue();
if(current == null)
continue;
q.Enqueue(current.Left);
q.Enqueue(current.Right);
DoSomething(current);
}
デキュー後にnull
を確認する代わりに、キューに追加する前に確認できます。私はコードをコンパイルしなかったので、いくつかの小さな間違いが含まれているかもしれません。
LINQとうまく統合できる、より洗練された(しかしより遅い)バージョン:
public static IEnumerable<T> BreadthFirstTopDownTraversal<T>(T root, Func<T, IEnumerable<T>> children)
{
var q = new Queue<T>();
q.Enqueue(root);
while (q.Count > 0)
{
T current = q.Dequeue();
yield return current;
foreach (var child in children(current))
q.Enqueue(child);
}
}
Children
のNode
プロパティと一緒に使用できます:
IEnumerable<Node> Children { get { return new []{ Left, Right }.Where(x => x != null); } }
...
foreach(var node in BreadthFirstTopDownTraversal(root, node => node.Children))
{
...
}
var queue = new Queue<BinaryNode>();
queue.Enqueue(rootNode);
while(queue.Any())
{
var currentNode = queue.Dequeue();
if(currentNode.data == searchedData)
{
break;
}
if(currentNode.Left != null)
queue.Enqueue(currentNode.Left);
if(currentNode.Right != null)
queue.Enqueue(currentNode.Right);
}