用于分割,遍历和跟踪对象的模式

时间:2008-11-18 13:10:13

标签: c# design-patterns

任何人都可以帮我找到一个优雅的设计来分割,遍历和跟踪物体。

下图显示了一个初始大小为100的对象,它被分成两个(50,75),然后其中一个子对象(75)被分成三个(25,25,25)。

我的问题是,任何人都可以想到一个优雅的设计,它允许我从任何对象遍历整个树(例如从任何后续子对象中识别根父)?

我当前的尝试(参见下面的代码)使用实例字段Parent和Children来跟踪对象,但它显然没有给我我需要的功能 - 从Obj [Id:6]我不能递归地找到根父

有人能想到解决方案吗?我认为双链表不会起作用,因为溢出参数不仅限于两个。

                      Obj [Id:1, Size:100]
                             |
                    Split operation (50, 75)
                             <>
       Obj [Id:2, Size:25]      Obj [Id:2, Size:75]
                                          |
                              Split operation (25, 25, 25)
                                          <>
         Obj [Id:4, Size:25]     Obj [Id:5, Size:25]       Obj [Id:6, Size:25]




public class SplitableObj : IEquatable<SplitableObj>
{
    private Guid _id = Guid.NewGuid();
    private int _size;
    private SplitableObj _parent;
    private List<SplitableObj> _childern;

    public SplitableObj(int size)
    {
        _size = size;
    }
    public Guid id
    {
        get { return _id; }
        set { _id = value; }
    }

    public SplitableObj Parent
    {
        get { return _parent; }
        set { _parent = value; }
    }

    public List<SplitableObj> Children
    {
        get { return _childern; }
        set { _childern = value; }
    }

    public int Size
    {
        get { return _size; }
        set { _size = value; }
    }

    public IEnumerable<SplitableObj> Split(params int[] splits)
    {
        if (splits.Length < 2)
        {
            throw new ApplicationException("splits must be least 2.");
        }

        int totalSplits = 0;
        foreach (int split in splits)
        {
            totalSplits += split;
        }

        if (_size != totalSplits)
        {
            throw new ApplicationException("Total splits must equal Size.");
        }

        foreach (int split in splits)
        {
            SplitableObj splitAmount = new SplitableObj(split);
            splitAmount.Parent = this;
            this.Children.Add(splitAmount);
            yield return splitAmount;
        }
    }

    public bool Equals(SplitableObj splitableObj)
    {
        if (splitableObj == null) return false;
        return Equals(_id, splitableObj._id);
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj)) return true;
        return Equals(obj as SplitableObj);
    }
    public override int GetHashCode()
    {
        return _id.GetHashCode();
    }
}

2 个答案:

答案 0 :(得分:1)

作业?

set RootObject to the current object.
while the parent of RootObject is not undefined, set RootObject to its parent.
Finally, return RootObject.

答案 1 :(得分:0)

为什么你难以找到根?从父母一直到父母,直到未设置父母。

是的,你在谈论B +树吗?他们使用在超过阈值时分割的子块自动平衡在维基百科中查看此图像image