我知道我来晚了。在查看这里提供的精彩答案后,我认为我的答案将为此帖子增加一些价值。虽然发布的答案很棒并且易于理解,但是所有答案都以线性时间计算BST的高度。我认为这可以改进,并且可以在< strong>常数时间内检索高度,因此写下这个答案 - 希望您会喜欢它。
让我们从
节点类开始:
public class Node
{
public Node(string key)
{
Key = key;
Height = 1;
}
public int Height { get; set; }
public string Key { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
public override string ToString()
{
return $"{Key}";
}
}
二叉搜索树(BinarySearchTree)类
你可能已经猜到了这里的技巧......我保留了节点实例变量 Height 来跟踪每个添加的节点。接下来,让我们转向 BinarySearchTree 类,它允许我们将节点添加到我们的 BST 中:
public class BinarySearchTree
{
public Node RootNode { get; private set; }
public void Put(string key)
{
if (ContainsKey(key))
{
return;
}
RootNode = Put(RootNode, key);
}
private Node Put(Node node, string key)
{
if (node == null) return new Node(key);
if (node.Key.CompareTo(key) < 0)
{
node.Right = Put(node.Right, key);
}
else
{
node.Left = Put(node.Left, key);
}
node.Height = Math.Max(GetHeight(node.Left), GetHeight(node.Right)) + 1;
return node;
}
private int GetHeight(Node node)
{
return node?.Height ?? 0;
}
public Node Get(Node node, string key)
{
if (node == null) return null;
if (node.Key == key) return node;
if (node.Key.CompareTo(key) < 0)
{
return Get(node.Right, key);
}
return Get(node.Left, key);
}
public bool ContainsKey(string key)
{
Node node = Get(RootNode, key);
return node != null;
}
}
一旦我们向BST中添加了键和值,我们只需在RootNode对象上调用Height属性,它将以常数时间返回我们RootNode树的高度。诀窍是在向树中添加新节点时保持高度更新。希望这对计算机科学爱好者的广大群众有所帮助!
单元测试:
[TestCase("SEARCHEXAMPLE", 6)]
[TestCase("SEBAQRCHGEXAMPLE", 6)]
[TestCase("STUVWXYZEBAQRCHGEXAMPLE", 8)]
public void HeightTest(string data, int expectedHeight)
{
var runner = GetRootNode(data);
Assert.AreEqual(expectedHeight, runner.RootNode.Height);
}
private BinarySearchTree GetRootNode(string data)
{
var runner = new BinarySearchTree();
foreach (char nextKey in data)
{
runner.Put(nextKey.ToString());
}
return runner;
}
注意:在每个Put操作中保持树的高度的想法,受到
算法(第四版)书第3章(第399页)中BST方法的启发。