Как сохранить интервал при отображении дерева при использовании обхода в ширину? - PullRequest
1 голос
/ 04 февраля 2012

Я понимаю, во-первых, но у меня возникли проблемы, так как я имею дело с отношениями один-ко-многим детям.

Моя объектная модель Родитель -> Дети (Многие)

Имея код, который у меня есть сейчас, я просто пишу в файл с помощью построителя строк, но в будущем я буду использовать автоматизацию Excel.

Точная проблема заключается в том, чтобы поддерживать вкладки так, чтобы дети отображались правильно.У каждого ребенка также могут быть дети.

{
        Queue<UserStory> storiesQueue = new Queue<UserStory>();
        StringBuilder printDocument = new StringBuilder();

        foreach (var userStorey in _rallyDownloader.GetUserStories().OrderBy(story => story.Name))
        {
            storiesQueue.Enqueue(userStorey);
        }
        int tabs = 0;
        while (storiesQueue.Count > 0)
        {
            string tab = "";
            for (int i = 0; i < tabs; i++)
            {
                tab += "|----";
            }
            var story = storiesQueue.Dequeue();

            printDocument.Append(tab + story.Name + "\n");

            tabs++;
            foreach (var child in story.Children)
            {
                string cTab = "";
                for (int i = 0; i < tabs; i++)
                {
                    cTab += "|----";
                }
                printDocument.Append(cTab + child.Name + "\n");

                foreach (var storey in child.Children)
                {
                    storiesQueue.Enqueue(storey);
                }


            }
        }
    }

Я пытался сохранить количество исходных корней и табуляции при достижении конца, но может быть более простой путь.

Я избегаю рекурсии, так какЯ имею дело с большим набором данных и у меня возникли проблемы с памятью.

В итоге я использовал идею стека и создал этот код.

StreamWriter stream = new StreamWriter(@"C:\awesomeSaucer.txt", true);
        Stack<UserStory> storiesQueue = new Stack<UserStory>();
        Stack<string> indentation = new Stack<string>();

        foreach (var userStorey in _rallyDownloader.GetUserStories().OrderBy(story => story.Name))
        {
            storiesQueue.Push(userStorey);
            indentation.Push("");
        }

        while (storiesQueue.Count > 0)
        {
            string tab = indentation.Pop();
            var story = storiesQueue.Pop();

            stream.WriteLine(tab + story.Name + "\n");

            // printDocument.Append(tab + story.Name + "\n");

            foreach (var child in story.Children)
            {
                indentation.Push(tab + "----");
                storiesQueue.Push(child);
            }
        }
        stream.Close();

1 Ответ

1 голос
/ 04 февраля 2012

Я бы использовал стек, который отражает фактическую глубину вашего обхода по его размеру, когда пройденные элементы были выдвинуты и вытолкнуты согласно текущей ветви. Это также позволит вам продолжить свой обход, не ставя детей в очередь. Таким образом, количество ваших вкладок будет равно stack.Count () - 1, если в корневом узле 0 вкладок. Основная идея заключается в том, что если вы хотите избежать переполнения стека потоков, вызванного рекурсией, вы можете бросить свой собственный стек в кучу.

...