0

I'm writing an interval tree in C#. What I'd like to do is just extend an existing binary search tree to store intervals and not have to rewrite the core functionality (add, get, delete).

Inside the BST, I have a Node class:

protected class Node 
{
    public KeyValuePair<TKey, TVal> Data;
    public Node Left, Right;

    public Node(KeyValuePair<TKey, TVal> data,
        Node left = null, Node right = null)
    {
        Data = data;
        Left = left; Right = right;
    }
}

And inside the interval tree, I have an IntervalNode class that extends Node:

private class IntervalNode : Node
{
    public Interval<TInterval> Interval;
    public override string ToString()
    {
        return string.Format("A={0}, B={1}", Interval.A, Interval.B);
    }

    public IntervalNode(KeyValuePair<TInterval, TVal> data, 
        Node left = null, Node right = null)
        : base(data, left, right)
    {
    }
}

The issue I'm running into is trying to store IntervalNode in the tree rather than Node. Is there any way I can now use the existing base implementations of Add with IntervalNode?

protected Node Add(Node root, KeyValuePair<TKey, TVal> data)
{
    // regular binary search tree insert
} 

I guess what I'd like to be able to do is something like this:

public void Add(Interval<TInterval> intvl, TVal val)
{
    _root = Add((Node)_root, new KeyValuePair<TInterval, TVal>(intvl.A, val));
    IntervalNode inserted = (IntervalNode)Get(_root, intvl.A);
    inserted.Interval = intvl;
}

// tree should store IntervalNodes, not Nodes
private IntervalNode _root;
DavidRR
  • 18,291
  • 25
  • 109
  • 191
rookie
  • 2,783
  • 5
  • 29
  • 43

1 Answers1

1

Your example code won't compile, but here is what I think you are trying to get at:

protected class Node
    {
        public KeyValuePair<TKey, TVal> Data;
        public Node Left, Right;

        public Node(KeyValuePair<TKey, TVal> data,
            Node left = null, Node right = null)
        {
            Data = data;
            Left = left; Right = right;
        }

        public virtual void Add(Node root, KeyValuePair<TKey, TVal> data)
        {
            //Do whatever
        }
    }

Then in the derived class:

private class IntervalNode: Node
    {
        public Interval<TInterval> Interval;
        public override string ToString()
        {
            return string.Format("A={0}, B={1}", Interval.A, Interval.B);
        }

        public IntervalNode(KeyValuePair<TInterval, TVal> data, 
            Node left = null, Node right = null)
            : base(data, left, right)
        {
        }

        public override void Add(Node root, KeyValuePair<TInterval, TVal> data)
        {
            //Do whatever you need to, then
            base.Add(root, data);
        }
    }

You'll need to fix the generics problem you have but you should be able to see the point.

Since IntervalNode is a Node, you can store it in the same place that the base class does, there isn't a need to cast it or to separate the storage out. That is a nice part about inheritance.

Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
  • Thanks, Ron. `Node` and `IntervalNode` are both inner classes of `BinarySearchTree` and `IntervalTree` respectively. I will look into your solution. – rookie May 13 '15 at 13:34