在c#中遍历树状结构

时间:2014-10-28 11:56:39

标签: c# .net

我正在构建一个逻辑来遍历下面提到的树状结构: -

A: Missing
|
|-B: missing
|                 |
|                 |
|                 |
|                 |C: real email
|
| D: Real Email
|
|
|
|E: Missing
                |
                |
                |
                | F: Missing
                                |
                                |
                                |
                                | G: Real
                                |
                                |H: Missing
                                                |
                                                |
                                                | I : real email
                                                                |
                                                                |
                                                                | J : real email

我必须使用递归来执行此操作,并且每个节点都是IEnumerable集合。

任何帮助都会非常感激

我试过下面提到的代码: -

 private List<RTAEMailCluster> getClustersForBetaEstimations(RTAEMailCluster childCluster, ref int depth)
    {
        //still working on this...

        if (childCluster.RTAEMailClusters.Count > 0)
        {
            for (int i = 0; i < childCluster.RTAEMailClusters.Count; i++)
            {
                if (!_filteredClusters.Contains(childCluster.RTAEMailClusters[i]))
                {
                    _filteredClusters.Add(childCluster);
                    getClustersForBetaEstimations(childCluster.RTAEMailClusters[i], ref depth);
                }
            }
            depth++;
        }
        return _filteredClusters;

    }

1 个答案:

答案 0 :(得分:0)

查看此示例代码,该代码使用递归来查找与特定谓词匹配的所有节点。

它使用了一个非常简化的Node类,因此它可以专注于解决问题。

我使用了谓词函数,因为它使它更灵活 - 你传入谓词而不是硬编码。您应该能够根据您的要求进行调整。

您可以将此代码编译并运行为控制台应用程序:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    // Basic Node with data and children.

    public sealed class Node
    {
        public string Data;
        public IEnumerable<Node> Children;
    }

    // Encapsulates finding nodes matching a particular predicate.

    public sealed class NodeFinder
    {
        // Maxmimum depth encountered so far while iterating over FindMatchingNodes().
        // The correct value will have been calculated once the FindMatchingNodes() iteration
        // is complete.

        public int MaxDepth
        {
            get
            {
                return _maxDepth;
            }
        }

        // Finds all the nodes that match a specified predicate.

        public IEnumerable<Node> FindMatchingNodes(Node root, Predicate<string> predicate)
        {
            _maxDepth     = 0;
            _currentDepth = 1;

            return findMatchingNodes(root, predicate);
        }

        // Recursively find all matching nodes.

        private IEnumerable<Node> findMatchingNodes(Node root, Predicate<string> predicate)
        {
            if (predicate(root.Data))
                yield return root;

            if (root.Children != null)
            {
                ++_currentDepth;
                _maxDepth = Math.Max(_currentDepth, _maxDepth);

                foreach (var child in root.Children.Where(c => c != null))
                    foreach (var matching in findMatchingNodes(child, predicate))
                        yield return matching;

                --_currentDepth;
            }
        }

        private int _maxDepth;
        private int _currentDepth;
    }

    public static class Program
    {
        private static void Main()
        {
            var root = makeSampleTree();

            NodeFinder nodeFinder = new NodeFinder(); // Use this to find nodes.

            // Print the data for all nodes where 'Data' ends with "0".

            var nodesWithDataEndingIn0 = nodeFinder.FindMatchingNodes(root, data => data.EndsWith("0"));

            foreach (var node in nodesWithDataEndingIn0)
                Console.WriteLine(node.Data);

            Console.WriteLine("Max depth = " + nodeFinder.MaxDepth);
        }

        private static Node makeSampleTree()
        {
            var root = new Node {Data = "Root"};
            addChildrenTo(root, 4, 0, 5, root.Data);
            return root;
        }

        private static void addChildrenTo(Node node, int numChildren, int depth, int maxDepth, string baseName)
        {
            var newChildren = makeChildren(baseName + ".", numChildren);

            if (depth < maxDepth-1)
                foreach (var child in newChildren)
                    addChildrenTo(child, numChildren, depth+1, maxDepth, baseName + "." + depth);

            node.Children = newChildren;
        }

        private static Node[] makeChildren(string baseName, int n)
        {
            var result = new Node[n];

            for (int i = 0; i < n; ++i)
                result[i] = new Node {Data = baseName + i};

            return result;
        }
    }
}