Шаблон для разделения, перемещения и отслеживания объектов - PullRequest
1 голос
/ 18 ноября 2008

может помочь мне найти элегантный дизайн для разделения, перемещения и отслеживания объектов.

На рисунке ниже показан объект с начальным размером 100, который разделен на два (50, 75), затем один из дочерних объектов (75) впоследствии разделен на три (25, 25, 25).

Мой вопрос: может ли кто-нибудь придумать элегантный дизайн, который позволил бы мне из любого объекта пройти по всему дереву (например, чтобы идентифицировать корневого родителя из любого последующего дочернего объекта)?

Моя текущая попытка (см. Код ниже) использует поля экземпляра Parent и Children для отслеживания объектов, но, очевидно, она не дает мне требуемой функциональности - в Obj [Id: 6] я не могу рекурсивно найти корневого родителя .

Кто-нибудь может придумать решение? Я не думаю, что двойной связанный список будет работать, так как параметр spilled не ограничен только двумя.

                      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 ]

1 голос
/ 18 ноября 2008

Домашнее задание

set RootObject to the current object.
while the parent of RootObject is not undefined, set RootObject to its parent.
Finally, return RootObject.
0 голосов
/ 18 ноября 2008

Почему у вас возникают трудности с поиском рута? переходить от родителя к родителю, пока родитель не будет установлен.

Кстати, вы говорите о деревьях B +? Они автоматически балансируют, используя блоки детей, которые разделяются при превышении порога, посмотрите на это изображение в Википедии image

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...