STL -> Tree
От: Holms США  
Дата: 13.10.03 12:36
Оценка:
Может плохо смотрел но почему-то в STL никак не мог найти структуру которая бы позволяла
хранить данные в виде дерева, как тот который мы видим в Windows Explorer. т.е. что-бы у каждого
предка могли быть N-ое количество детей.

Из-за того что не нашел ничего хорошего сляпал кое-что сам. Посмотрите и поправте где не прав.
(Функциональность, пока, только то что мне надо)


#include <vector>
#include <iostream>
#include <stdexcept>

using namespace std;

template <class T>
class hTreeItem{
  typedef std::vector<hTreeItem*> tagItems;
  typedef typename tagItems::iterator tagItemsIter;
  typedef typename tagItems::const_iterator tagItemsIterC;
private:
  T _data;
  hTreeItem *_parent;
  std::vector<hTreeItem*> _children;

  void destroy();
public:
  hTreeItem(hTreeItem* parent,const T& data)
    : _data(data), _parent(parent){
    }
  ~hTreeItem(){
    destroy();
  }
public:
  const typename tagItems::size_type size() const { return _children.size(); }
  tagItemsIter begin() { return _children.begin(); }
  tagItemsIter end() { return _children.end(); }
  tagItemsIterC begin() const { return _children.begin(); }
  tagItemsIterC end() const { return _children.end(); }

  hTreeItem* push_back(hTreeItem* item);
  hTreeItem* push_back(const T& data) { return push_back( new hTreeItem<T>(this, data) ); }
  hTreeItem* push_front(hTreeItem* item);
  hTreeItem* push_front(const T& data) { return push_front( new hTreeItem<T>(this, data) ); }
  hTreeItem* getAt(typename tagItems::size_type index){
    if( index >= _children.size() ) throw std::runtime_error("Index out of bounds.");
    return _children[index];
  }
  const hTreeItem* getAt(typename tagItems::size_type index) const{
    if( index >= _children.size() ) throw std::runtime_error("Index out of bounds.");
    return _children[index];
  }
  const T data() const { return _data; }
};

template<class T>
void hTreeItem<T>::destroy()
{
  tagItemsIter beg = _children.begin(), end =_children.end();
  while( beg != end )
  {
    delete (*beg);
    ++beg;
  }
  _children.clear();
}

template <class T>
hTreeItem<T>* hTreeItem<T>::push_back(hTreeItem<T>* item)
{
  if( !item ) throw std::runtime_error("[push_back] Cannot insert NULL item.");
  item->_parent = this;
  _children.push_back( item );
  return item;
}

template<class T>
hTreeItem<T>* hTreeItem<T>::push_front(hTreeItem<T>* item)
{
  if( !item ) throw std::runtime_error("[push_front] Cannot insert NULL item.");
  item->_parent = this;
  _children.push_front( item );
  return item;
}

void outSpace(int iLevel)
{
  for( int i = 0; i < iLevel; i++ )
    cout << "  ";
}

template <class T>
void outTree(hTreeItem<T>* root, int iLevel, int iPos)
{
  if( root )
  {
    outSpace( iLevel ); cout << root->data() << endl;
    if( iPos < root->size() ) outTree( root->getAt(iPos), iLevel + 1,0 );
    iPos++;
    while( iPos < root->size() )
    {
      hTreeItem<T> *item = root->getAt(iPos);
      if( item )
        outTree( item , iLevel + 1, 0 );
      iPos++;
    }
  }
}

int main()
{
  try
  {
  hTreeItem<int>  intItem(NULL,1);
  hTreeItem<int> *p, *p1;

  intItem.push_back(11);
  p = intItem.push_back(12);
  p->push_back(121);
  p->push_back(122);
  p->push_back(123);
  p1 = p->push_back(124);
  p1 = p1->push_back(1241);
  p1->push_back(12411);
  p->push_back(125);
  p->push_back(126);
  hTreeItem<int> *i = new hTreeItem<int>(NULL, 3);
  p = intItem.push_back( i );
  p = p->push_back( 222 );
  intItem.push_back( 13 );
   p = intItem.push_back( 15 );
   p = p->push_back(12);
   p = p->push_back(100);
   p = p->push_back(666);
  cout << "Size=" << intItem.size() << " = " << p->size() << endl;

    outTree( &intItem, 0, 0 );
  }
  catch(runtime_error &er)
  {
    cout << er.what();
  }
  
  return 1;
}
... << RSDN@Home 1.1 beta 2 >>
The life is relative and reversible.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.