Сохраняем список элементов, хранящихся в рекурсивном классе?


Ну, название на самом деле ничего не объяснить, поэтому я приведу сокращенный вариант моего кода:

class Handler {
    Dictionary<object, Leaf> AllItems = new Dictionary<object, Leaf>(); //This list

    Leaf RootLeaf = new Leaf();
    public void Add (object obj)
    {
        Leaf AddedTo = RootLeaf.Add(obj); //Adds to a leaf, then returns the leaf it was added to
        AllItems.Add(obj, AddedTo); //adds references to the obj and the leaf it's in.
    }
}

class Leaf {
    private Leaf _Parent;
    public Leaf SubLeaf;
    public List<object> Children = new List<object>();

    public Leaf (Leaf parent)
    {
        this._Parent = parent;
    }

    public void Add (object obj)
    {
        if (Children.Count > 5)
        {
            SubLeaf = new Leaf();
            return SubLeaf.Add(obj); //recursively return the reference to the end leaf
        }
        Children.Add(obj);
        return this; //start the recursive return
    }

    public Leaf Parent { get { return this._Parent; } }
}

Примечание: выше-это не реальный код, просто пример того, что я планирую сделать.

Поэтому идея заключается в том, чтобы организовать все элементы в листьях, но мне нужен быстрый способ, чтобы цикл через каждый объект, так и его листья. Будет делать выше (сохраняя ссылку на каждый объект и его родителем в список в классе обработчика) вызовет падение производительности? Или может, есть лучший способ сделать это?

Я надеюсь, это было достаточно ясно, если нет, пожалуйста, задать любые вопросы.



2953
2
c#
задан 21 ноября 2011 в 06:11 Источник Поделиться
Комментарии
1 ответ

Ну, это не дерево, это связанный список, и он не будет работать должным образом на протяжении более чем семи пунктов. После этого вам будут перезаписывать SubLeaf переменной в первом узле, и ранее добавленные элементы будут удалены из списка, и AllItems будет содержать потерянные вещи с открестился узлов.

Чтобы сделать список работы вы должны проверить, если узел имеет следующий узел, прежде чем создавать новую.

public class Node {

private Node _next;
private List<object> _items;

public Node Previous { get; private set; }

public Leaf (Leaf previous) {
_previous = previous;
_next = null;
_items = new List<object>(6);
}

public void Add(object obj) {
if (_items.Count == 6) {
if (_next == null) {
_next = new Leaf(this);
}
return _next.Add(obj);
}
_items.Add(obj);
return this;
}

}

Примечание: рекомендуется использовать массив в узле вместо списка. Создаете список, который использует списки, кажется излишним...

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

Сдачи объектов и их узлов в список не требуется для перебора их, а у вас уже есть все узлы и объекты. Добавление в список будет примерно тройной объем памяти и время, чтобы добавить элемент. Вам нужно будет только другой список, если вам нужно два совершенно разных способа доступа к позиции, например как предсказуемое перечисление и хэш-поиска.

Перечислять список пар объектов и узлов, вы можете поставить перечислитель в узел класс, который получает все объекты и их узлов из текущего узла и вперед, так что вы просто использовать его на первом узле, чтобы получить все объекты:

public IEnumerable<KeyValuePair<object,Node>> GetAll() {
Node node = this;
while (node != null() {
foreach (object obj in node._items) {
yield return new KeyValuePair<object,Node>(obj, node);
}
node = node._next;
}
}

3
ответ дан 21 ноября 2011 в 08:11 Источник Поделиться