попинайте пожалуйста ещё одно дерево
От: nen777w  
Дата: 26.10.10 13:36
Оценка:
Придумал вот такую реализацию дерева.
Итераторы пока не прикрутил сюда.
Попинайте plz кому не лень.

namespace tree {

    //---------------------------------------------------------------------------------
    struct  container_operation_core
    {
        template< typename TFacade, typename TData >
        static  bool    insert( TFacade& f, TData& d ) {
            return f.impl_insert( d );
        }

        template< typename TFacade >
        static bool    remove( TFacade& f, unsigned int idx ) {
            return f.impl_remove( idx );
        }

        template< typename TFacade >
        static void     remove_all( TFacade& f ) {
            return f.impl_remove_all();
        }

        template< typename TFacade, typename TData >
        static TData&  at( TFacade& f, unsigned int idx ) {
            return f.impl_at( idx );
        }

        template< typename TFacade >
        static unsigned int total( TFacade& f ) {
            return f.impl_total();
        }
    };
    //.................................................................................
    template< 
        typename TDerived
        , typename TData
    >
    struct  container
    {
        TDerived&   derived() { return *static_cast<TDerived*>(this); }
        const TDerived&   derived() const { return *static_cast<const TDerived*>(this); }

        bool    insert( TData& data ) {
            return container_operation_core::insert( this->derived(), data );
        }

        bool    remove( unsigned int idx ) {
            return container_operation_core::remove( this->derived(), idx );
        }

        void    remove_all() {
            container_operation_core::remove_all(  this->derived() );
        }

        TData&  operator[]( unsigned int idx ) {
            return container_operation_core::at<TDerived, TData>( this->derived(), idx );
        }

        unsigned int    total() const {
            return container_operation_core::total( this->derived() );
        }
    };
    //---------------------------------------------------------------------------------
    //.................................................................................
    //implementation 4 vector
    struct  use_std_vector {
        template< typename T > 
        struct subtype { 
            typedef std::vector<T> container;

            static bool    impl_insert( container& c, const T& data ) {
                c.push_back( data );
                return true;
            }
            static bool    impl_remove( container& c, unsigned int idx ) {
                if( idx > c.size() ) return false;
                c.erase( c.begin()+idx );
                return true;
            }
            static void    impl_remove_all( container& c ) {
                c.clear();
            }
            static T&    impl_at( container& c, unsigned int idx ) {
                return c[idx];
            }
            static unsigned  impl_total( const container& c ) {
                return c.size();
            }
        };
    };

    //---------------------------------------------------------------------------------
    //tree node
    template<
            typename TData
        ,   typename node_container
    >
    struct  tree_node : public container< tree_node<TData, node_container>, tree_node<TData, node_container> >
    {
        typedef TData   data_t;
        typedef tree_node<TData, node_container>    self_t;
        typedef typename node_container::subtype<self_t> subtype_t;
        typedef typename subtype_t::container  childs_container;

        tree_node()
            : m_pparent(NULL)
        {}

        tree_node( TData data ) 
            : m_data(data) 
        {}

    private:
        friend class    container_operation_core;

        bool    impl_insert( self_t& data ) {
            data.set_parent( this );
            return subtype_t::impl_insert( m_childs, data );
        }
        bool    impl_remove( unsigned int idx ) {
            return subtype_t::impl_remove( m_childs, idx );
        }
        void    impl_remove_all() {
            subtype_t::impl_remove_all( m_childs );
        }
        self_t&    impl_at( unsigned int idx ) {
            return subtype_t::impl_at( m_childs, idx );
        }
        unsigned  impl_total() const {
            return subtype_t::impl_total( m_childs );
        }

    private:
        void    set_parent( self_t* p ) { m_pparent = p; }

    private:
        self_t*             m_pparent;
        childs_container    m_childs;
        data_t              m_data;
    };

    //---------------------------------------------------------------------------------
    //basic tree
    template<
            typename TData
        ,   typename container = use_std_vector
    >
    struct basic_tree 
    {
        typedef tree_node<TData, container> node_t;

        node_t& root() { return m_root; }

    private:
        node_t  m_root;
    };
}


использование:

    typedef tree::basic_tree<int>   test_tree_t;

    test_tree_t tree;

    tree.root().remove_all();
    tree.root().insert( test_tree_t::node_t(0) );
    tree.root().insert( test_tree_t::node_t(1) );
    tree.root()[0].insert( test_tree_t::node_t(3) );
    tree.root()[0][0].insert( test_tree_t::node_t(4) );
    tree.root()[0][0][0].insert( test_tree_t::node_t(5) );
    tree.root()[0][0].remove( 0 );
Re: попинайте пожалуйста ещё одно дерево
От: peterbes Россия  
Дата: 26.10.10 14:09
Оценка:
Здравствуйте, nen777w, Вы писали:

Вообще-то это вовсе не дерево.

В качестве контейнера взят вектор, почему не map? Когда число элементов вырастет, дерево умрёт на вставках и удалениях.
Кроме того, такая запись выглядит крайне неприятно
    tree.root()[0][0][0].insert( test_tree_t::node_t(5) );
    tree.root()[0][0].remove( 0 );


против

   node* child1 = parent->node(val0);
   child2 = child1->node(val1);


Что за обращения у вас к индексам? Как же это будет выглядеть, когда степень вложенности станет равной к примеру 100?
Чем ваше дерево отличается от матрицы смежности? Если вы решили отобразить дерево таким образом, то стоило ли делать этот комбайн с массивами? Можно было бы отдельно хранить матрицу, отдельно на мапах хранить содержимое дерева.
Re: попинайте пожалуйста ещё одно дерево
От: Vain Россия google.ru
Дата: 26.10.10 14:17
Оценка: 1 (1)
Здравствуйте, nen777w, Вы писали:

N>Придумал вот такую реализацию дерева.

N>Итераторы пока не прикрутил сюда.
N>Попинайте plz кому не лень.
А чем tcl не подошел?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: попинайте пожалуйста ещё одно дерево
От: Mr.Delphist  
Дата: 27.10.10 07:30
Оценка:
Идеологическое возражение: зачем у Вас вооще basic_tree объявлен? Создавайте tree_node, если он без родителя — то будет корневым.
Re[2]: попинайте пожалуйста ещё одно дерево
От: nen777w  
Дата: 08.11.10 08:50
Оценка:
Здравствуйте, peterbes, Вы писали:

P>Здравствуйте, nen777w, Вы писали:


P>Вообще-то это вовсе не дерево.


P>В качестве контейнера взят вектор, почему не map? Когда число элементов вырастет, дерево умрёт на вставках и удалениях.

Контейнер можно легко изменить на другой, либо вообще реализовать доступ/вставку к элементам по другому (например читать их с диска)
, реализовав соответствующие интерфейсы у такого класса.

P>Кроме того, такая запись выглядит крайне неприятно

P>
P>    tree.root()[0][0][0].insert( test_tree_t::node_t(5) );
P>    tree.root()[0][0].remove( 0 );
P>


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