Есть ли более краткий способ найти верхний узел в дереве, который соответствует критерию - PullRequest
0 голосов
/ 15 мая 2019

Для данного узла в дереве я пытаюсь найти его наивысшего предка (или самого узла), но без пересечения определенного "барьера" в дереве (определенного типа узла) - если есть такой «барьерный» узел. Если нет узла «барьер», я хочу вернуть верхний узел в дереве.

Звучит сложнее, чем есть - вот код:

    public Node GetHighestRelevantAncestorOrSelf(Node node)
    {
        Node topNode = node;
        bool newTopNodeFound;
        do
        {
            Node newTopNode = GetParent(topNode);

            newTopNodeFound = (newTopNode != null && !IsBarrierNode(newTopNode));

            if (newTopNodeFound)
            {
                topNode = newTopNode;
            }
        } while (newTopNodeFound);

        return topNode;
    }

Есть ли лучший способ написать это, то есть без оценки "newTopNodeFound" дважды? Может быть, используя цикл for?

Ответы [ 3 ]

1 голос
/ 15 мая 2019

Избавьтесь от него целиком.

public Node GetHighestRelevantAncestorOrSelf(Node node)
{
    Node topNode = null;
    while(node != null && !IsBarrierNode(node))
        node = GetParent(topNode = node);
    return topNode;
}

Хотя есть небольшая разница в функциональности между этим и тем, что у вас есть.Если ваш переданный в node является барьерным узлом, вы бы вернули этот узел, вместо этого вернулось бы null.Если вы хотите изменить это, измените строку Node topNode = null; на Node topNode = node;

0 голосов
/ 15 мая 2019

Один из способов сделать это без изменения исходного узла - создать новую переменную, которая ссылается на него, а затем «увеличить» эту переменную в цикле while(true), который устанавливает его в родительский узел, если он действителен:

public Node GetHighestRelevantAncestorOrSelf(Node node)
{
    Node result = node;

    while (true)
    {
        Node parent = GetParent(result);
        if (parent == null || IsBarrierNode(parent)) return result; // This exits the loop
        result = parent;
    }
}
0 голосов
/ 15 мая 2019

Вы можете использовать рекурсию

public Node GetTopNode(Node node)
{
    var parent = GetParent(node);
    return (parent != null && !IsBarrierNode(parent))
        ? GetTopNode(parent)
        : node;
}
...