C# 用于分割、遍历和跟踪对象的模式

C# 用于分割、遍历和跟踪对象的模式,c#,design-patterns,C#,Design Patterns,任何人都可以帮我找到一个优雅的设计,用于分割、遍历和跟踪对象 下图显示了一个初始大小为100的对象,该对象分为两个(50,75),然后一个子对象(75)随后分为三个(25,25,25) 我的问题是,是否有人能想出一种优雅的设计,允许我从任何对象遍历整个树(例如,从任何后续子对象识别根父对象) 我当前的尝试(参见下面的代码)使用实例字段Parent和Children来跟踪对象,但它显然没有提供我所需要的功能——从Obj[Id:6]开始,我无法递归地找到根父对象 有人能想出解决办法吗?我不认为一个双

任何人都可以帮我找到一个优雅的设计,用于分割、遍历和跟踪对象

下图显示了一个初始大小为100的对象,该对象分为两个(50,75),然后一个子对象(75)随后分为三个(25,25,25)

我的问题是,是否有人能想出一种优雅的设计,允许我从任何对象遍历整个树(例如,从任何后续子对象识别根父对象)

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

有人能想出解决办法吗?我不认为一个双链接列表会起作用,因为spilt参数不限于两个

                      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();
    }
}
Obj[Id:1,大小:100]
|
拆分操作(50,75)
Obj[Id:2,尺寸:25]Obj[Id:2,尺寸:75]
|
拆分操作(25、25、25)
Obj[Id:4,尺寸:25]Obj[Id:5,尺寸:25]Obj[Id:6,尺寸:25]
公共类SplitableObj:IEquatable
{
私有Guid _id=Guid.NewGuid();
私人国际单位大小;
私有可拆分对象的父对象;
私人名单(childern);;
公共可拆分对象(整数大小)
{
_大小=大小;
}
公共Guid id
{
获取{return\u id;}
设置{u id=value;}
}
公共可拆分对象父对象
{
获取{return\u parent;}
设置{u parent=value;}
}
公开儿童名单
{
获取{return\u childern;}
设置{u childern=value;}
}
公共整数大小
{
获取{return\u size;}
设置{u size=value;}
}
公共IEnumerable拆分(参数int[]拆分)
{
如果(拆分长度<2)
{
抛出新的ApplicationException(“拆分必须至少为2”);
}
int totalSplits=0;
foreach(整数拆分为拆分)
{
总拆分+=拆分;
}
如果(_size!=totalSplits)
{
抛出新的ApplicationException(“总拆分必须等于大小”);
}
foreach(整数拆分为拆分)
{
拆分对象拆分金额=新拆分对象(拆分);
splitAmount.Parent=this;
this.Children.Add(拆分金额);
收益率和收益率;
}
}
公共bool等于(SplitableObj SplitableObj)
{
if(splitableObj==null)返回false;
返回等于(_id,splitableObj._id);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(this,obj))返回true;
返回等于(obj作为可拆分obj);
}
公共覆盖int GetHashCode()
{
返回_id.GetHashCode();
}
}

为什么查找根目录时遇到困难?从一个父级转到另一个父级,直到未设置父级


顺便说一句,你说的是B+树吗?它们使用超过阈值时分割的子对象块自动平衡查看wikipedia中的这张图像为什么在查找根时遇到困难?从一个父级转到另一个父级,直到未设置父级

顺便说一句,你说的是B+树吗?他们使用超过阈值时被分割的子块自动平衡查看维基百科中的这张图片

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

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

将大小为100的对象拆分为大小为50和大小为75的对象的含义是什么?是否存在重叠?您的
\u childern
变量包含令人困惑的打字错误。在树状视图中,Id为3的Obj显示错误,Id为2。为什么设置
\u Id
不是构造函数的一部分?将大小为100的对象拆分为大小为50和大小为75的意义是什么?是否存在重叠?您的
\u childern
变量包含令人困惑的打字错误。在树状视图中,Id为3的Obj显示错误,Id为2。为什么设置
\u Id
不是构造函数的一部分?