好的,我已经有了一个基本的二进制搜索树类,它取决于内部Node类来存储数据。它就像这样(只显示这里的骨头):
public class TreeSet<T> where T : IComparable<T>
{
private Node root = null;
public void Insert(T t)
{
if (root == null)
root = new Node(t);
else
root.Insert(t);
}
internal class Node
{
protected Node left, right;
private T data;
public Node(T t)
{
data = t;
}
public virtual void Insert(T t)
{
int compare = t.CompareTo(data);
if (compare < 0)
{
if (left == null)
left = new Node(t);
else
left.Insert(t);
}
else if (compare > 0)
{
if (right == null)
right = new Node(t);
else
right.Insert(t);
}
}
}
}
还有更多内容,显然是搜索方法,枚举器等,但这些都是相关的。现在这只是一个基本的BST,并没有做任何事情来尝试确保它是平衡的或任何东西,但它处理所有的插入和搜索逻辑。如果我试图将其扩展为制作AVL树或Red-Black或其他东西,我们会遇到问题......
public class AvlTree<T> : TreeSet<T> where T : IComparable<T>
{
internal new class Node : TreeSet<T>.Node
{
public Node(T t) : base(t) {}
public int Depth
{
get
{
if (left == null && right == null)
return 0;
else if (left == null)
return right.Depth + 1;
else if (right == null)
return left.Depth + 1;
else
return Max(left.Depth, right.Depth) + 1;
}
}
public override void Insert(T t)
{
base.Insert(t);
//Do the AVL balancing stuff
}
}
}
已经存在问题 - left
和right
变量在父类中声明为TreeSet<T>.Node
,而不是AvlTree<T>.Node
。但我需要Depth
变量来确定是否需要平衡。当然,我可以强制转换它们,但这不起作用,因为节点是在父{Q}}函数中创建的,并且不是正确的类。我当然可以将所有代码复制到一个新的非扩展类中,但这是很多重复的代码,而且大部分都是相同的。 (我也可能制作一个Red-Black或Splay树,除了平衡算法之外,它们也大致相同。)最后,为所有这样的BST设置一个父类是很有用的,所以我可以改变哪个树我正在使用而不使用树更改代码。 (直到全面扩大,很难说哪种平衡算法会表现得更好。)
有没有什么好方法可以处理这类事情?那就是 - 确保Insert()
和left
变量存储适当的子类,并创建为正确的类,即使它们是由父类创建的?或者在这种情况下尝试重用代码只是一个错误,而且我最好将AvlTree与TreeSet完全分开,尽管代码重复?