C# - 根据深度值和列表索引创建树状结构

C# - Create tree like structure based on depth values and list indexes

我正在尝试创建一个 tree-like 结构。每个 class 都有一个 parent 字段和 children 列表,即 class 与 parent class 相同。基本的东西。

这是我正在使用的 class 的基本版本。

public class TreeElement {
    public string name;
    public int depth;
    public int id;

    public TreeElement parent;
    public List<TreeElement> children = new List<TreeElement>();
}

现在,当我获得初始数据时,我会在一个列表中获得所有这些 class。我的树视图中的每个项目都在一个大列表中,我所能继续的就是列表中项目的深度值和索引。所以列表基本上看起来像这样:

(0) -1
(1)  |- 0
(2)     |-- 1
(3)     |-- 1
(4)     |   |-- 2
(5)     |-- 1

(x) 表示列表中的索引。其余数字是深度值。

现在谈谈我的实际问题。我很难根据这些值制作自己的列表,而且我基本上只能在每个 child 中添加一个项目,而忽略兄弟姐妹。我真的找不到办法将这些考虑在内。

到目前为止,这是我的代码(这可能是非常错误的):

private List<TreeElement> GenerateTreeStructure(List<TreeElement> baseList)
{
    // Base list is the list I get provided with.
    List<TreeElement> newList = new List<TreeElement>();
    TreeElement root = null;
    TreeElement previousFolder = null;
    int previousdepth = -99;

    for (int i = 0; i < baseList.Count; i++)
    {
        TreeElement currentResource = baseList[i];
        if (currentResource.depth == -1 && ShowRootFolder) // The root folder.
        {
            root = currentResource;
            // (Name, depth, parent)
            newList.Add(new TreeElement("Root", currentResource.depth, null));
            previousFolder = root;
            previousdepth = root.depth;
        }
        else if (!ShowRootFolder && currentResource.depth <= 0)
        {
            // If root folder is not shown, take all the children of the root folder instead.
            if (currentResource.depth != -1)
            {
                previousFolder = new TreeElement(currentResource.name, currentResource.depth, null);
                previousdepth = previousFolder.depth;
                newList.Add(previousFolder);
            }
        }
        else
        {
            if (currentResource.depth > previousdepth)
            {
                TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, null);
                previousFolder.children.Add(newResource);
                previousdepth = currentResource.depth;
                previousFolder = newResource;
            }
        }
    }

    return newList;
}

我希望这能解释我的问题。我已经坚持了很长一段时间,我希望得到一些帮助!

谢谢

我发现了两个逻辑错误。这是固定代码:

  // Base list is the list I get provided with.
        List<TreeElement> newList = new List<TreeElement>();
        TreeElement root = null;
        TreeElement previousFolder = null;
        int previousdepth = -99;

        for (int i = 0; i < baseList.Count; i++)
        {
            TreeElement currentResource = baseList[i];
            if (currentResource.depth == -1 && ShowRootFolder) // The root folder.
            {
                root = new TreeElement("Root", currentResource.depth, null);
                // (Name, depth, parent)
                newList.Add(root);
                previousFolder = root;
                previousdepth = root.depth;
            }
            else if (!ShowRootFolder && currentResource.depth <= 0)
            {
                // If root folder is not shown, take all the children of the root folder instead.
                if (currentResource.depth != -1)
                {
                    previousFolder = new TreeElement(currentResource.name, currentResource.depth, null);
                    previousdepth = previousFolder.depth;
                    newList.Add(previousFolder);
                }
            }
            else
            {
                if (currentResource.depth > previousdepth)
                {
                    TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, previousFolder);
                    previousFolder.children.Add(newResource);
                    previousdepth = currentResource.depth;
                    previousFolder = newResource;
                }
            }
        }

        return newList;

在第一个 "if" 语句中,您创建了新的 Root 但没有将其分配给根对象,因此也没有将其分配给您在最后一个 "if" 语句中使用的 previousFolder 对象。此外,您没有在最后一个 if 语句中将 previousFolder 对象传递给 TreeElement 的构造函数,如果您尝试使用父字段从底部转到根元素,则会导致问题。

P.S。代码很奇怪,看起来你才刚刚开始学习。如果我们在谈论树结构,我建议阅读有关 Composite pattern to create a tree in couple with Visitor pattern 到 'visit' 的内容。

有点奇怪为什么要从那个 GenerateTreeStructure 函数返回一个 TreeElement 列表?您正在制作树结构吗?你应该只返回根节点?无论如何,这需要一个包含深度值的列表并从中生成一棵树:

public static TreeElement GenerateTreeStructure(List<TreeElement> baseList)
{
    TreeElement root = null;
    if (baseList == null || baseList.Count == 0) return root;

    int baseIdx = -1;

    TreeElement prevNode = null;
    TreeElement parent = null;

    while (baseIdx < baseList.Count - 1)
    {
        baseIdx++;
        TreeElement item = baseList[baseIdx];

        if (item.depth == -1)
        {
            root = new TreeElement("root", -1, null);
            prevNode = root;
            continue;
        }

        if (item.depth == prevNode.depth) parent = prevNode.parent; // same level as prevNode
        else if (item.depth > prevNode.depth) parent = prevNode;    // deeper
        else                                                        // shallower
        {
            parent = prevNode.parent;
            while (parent.depth >= item.depth) parent = parent.parent;
        }

        TreeElement newNode = new TreeElement(item.name, item.depth, parent);
        parent.children.Add(newNode);
        prevNode = newNode;
    }

    return root;
}

// to test
void Traverse(TreeElement branch, int depth)
{
    log(new string('\t', depth) + branch.name);
    foreach (var subBranch in branch.children) Traverse(subBranch, depth+1);
}

Traverse(root, 0);