Как сделать дерево в C++?


6

Как создать структуру данных дерева в C++, которая использует итераторы вместо указателей? Я ничего не мог найти в STL, который мог бы это сделать. То, что я хотел бы сделать это, чтобы иметь возможность создавать и манипулировать деревья, как это:

#include <iostream> 
#include <tree> 
using namespace std; 

int main() 
{ 
    tree<int> myTree; 

    tree<int>::iterator i = myTree.root(); 
    *i = 42; 

    tree<int>::iterator j = i.add_child(); 
    *j = 777; 
    j = j.parent(); 

    if (i == myTree.root() && i == j) cout << "i and j are both pointing to the root\n"; 

    return 0; 
} 

Спасибо, tree.hh, кажется, только то, что я искал.

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

Карта представляет собой ассоциативный контейнер, который имеет гарантию исполнения идентичных таковые из дерева: логарифмическая поисковые, логарифмическая вставки, логарифмического удаления, линейное пространство. Внутренне они часто реализуются как красно-черные деревья, хотя это не является гарантией. Тем не менее, как пользователь STL все, что вам нужно знать, - это гарантии качества STL алгоритмов и структур данных. Являются ли они реализованы как деревья или маленькие зеленые мужчины не должны иметь значения вам.

Я не уверен, что карта - это то, что мне нужно, но спасибо за информацию. Я буду помнить, чтобы использовать карты, когда это возможно, вместо реализации деревьев.

5

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

Вот фрагмент кода, извлеченный с его сайта.

int main(int, char **) 
    { 
    tree<string> tr; 
    tree<string>::iterator top, one, two, loc, banana; 

    top=tr.begin(); 
    one=tr.insert(top, "one"); 
    two=tr.append_child(one, "two"); 
    tr.append_child(two, "apple"); 
    banana=tr.append_child(two, "banana"); 
    tr.append_child(banana,"cherry"); 
    tr.append_child(two, "peach"); 
    tr.append_child(one,"three"); 

    loc=find(tr.begin(), tr.end(), "two"); 
    if(loc!=tr.end()) { 
     tree<string>::sibling_iterator sib=tr.begin(loc); 
     while(sib!=tr.end(loc)) { 
     cout << (*sib) << endl; 
     ++sib; 
     } 
     cout << endl; 
     tree<string>::iterator sib2=tr.begin(loc); 
     tree<string>::iterator end2=tr.end(loc); 
     while(sib2!=end2) { 
     for(int i=0; i<tr.depth(sib2)-2; ++i) 
      cout << " "; 
     cout << (*sib2) << endl; 
     ++sib2; 
     } 
     } 
    } 

Теперь что нового? Ваша реализация проще, когда дело доходит до , присоединить узел к дереву. Хотя ваша версия неразборчиво проще, разработчик этой библиотеки, вероятно, хотел иметь доступную информацию без просмотра дерева, например, например, размер дерева.

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


3

Зачем вам это нужно? Если это предназначено для обучения, вы можете написать свою собственную структуру данных дерева. Если это для того, чтобы получить выгоду от структуры данных, содержащей произвольные типы индексов, оптимизированные для поиска и хорошего при вставке, рассмотрите возможность использования карты.

Карта представляет собой ассоциативный контейнер, который обладает гарантией производительности, идентичной характеристикам дерева: логарифмический поиск, логарифмическая вставка, логарифмическое удаление, линейное пространство. Внутри они часто реализуются как красно-черные деревья, хотя это не гарантия. Тем не менее, как пользователь STL, вам все равно, что это гарантии производительности алгоритмов STL и структур данных. Независимо от того, реализованы ли они как деревья или маленькие зеленые люди, это не имеет значения для вас.

В качестве примечания стороны нет функции root(). Все контейнеры STL имеют функцию begin(), реализующую концептуальное начало контейнера. Тип итератора, возвращаемого этой функцией, зависит от характеристик контейнера.