Modifying extended inner class

80 Views Asked by At

Okay, so I've got a basic Binary Search tree class I've made, which depends on an internal Node class to store the data. It goes something like this (just showing the bare bones here):

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);
            }
        }
    }
}

There's more to it, obviously search methods, enumerators, etc., but these are the relevant bits. Now this is just a basic BST, and doesn't do anything to try and ensure it's balanced or anything, but it handles all the insertion and searching logic. If I were to try and extend this to make an AVL tree or Red-Black or something, we run into problems...

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
        }
    }
}

Already there's a problem - the left and right variables are declared in the parent class to be TreeSet<T>.Node, and are not AvlTree<T>.Node. But I need the Depth variable to determine if balancing is needed. I can cast them, of course, but that won't work because the nodes are created in the parent's Insert() function, and will not be the right class. I could of course just copy all the code into a new, non-extended class, but that's a lot of duplicated code and most of it will be the same. (I might also make a Red-Black or Splay tree, which would also be mostly the same except for the balancing algorithms.) And ultimately, it can be useful to have one parent class for all such BSTs, so I could change which tree type I'm using without altering the code using the tree. (Until this goes full scale, it's hard to say which balancing algorithm will perform better.)

Is there any good way to handle this sort of thing? That is - making sure the left and right variables store the appropriate sub-class, and are created as the correct class, even if they are created by the parent class? Or is it just a mistake to even try to reuse the code in this case, and I'd be better off making the AvlTree completely separate from the TreeSet, despite the duplicated code?

0

There are 0 best solutions below