分享

想用C++写一个多叉树的结构

 zale的图书馆 2011-06-30
要抛弃原来C的思想,用C++标准的东西写一颗树

主要找到以下两个不同的代码实现: 先研究第一个

一个简单的多叉树实现:

  1. 利用迭代器方便地构建树,
  2. 可以递归输出,前序,后序。
  3. 利用栈实现输出。
  4. 销毁树只能后序遍历

类的定义:

  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. #include <stack>  
  5. #include <cassert>  
  6. using namespace std;  
  7. template<class T>  
  8. class htree_node{  
  9. public:  
  10.     typedef htree_node<T> node_type;  
  11.     htree_node()  
  12.         :parent(0),format("  ")  
  13.     {}  
  14.     htree_node(const T& x)        
  15.         :name(x), parent(0), format("  ")  
  16.     {}  
  17.     ~htree_node()  
  18.     {}  
  19.     T name;  
  20.     //默认为两个空格  
  21.     std::string format;  
  22.     node_type *parent;  
  23.     std::vector<node_type*> children;  
  24. };  
  25. template<class T, class Container = htree_node<T> >  
  26. class htree{  
  27. protected:  
  28.     typedef Container tree_node;          
  29. public:  
  30.     htree()  
  31.         :root(0)  
  32.     { Init(); }  
  33.     htree(tree_node *node)  
  34.         :root(node)  
  35.     { Init(); }  
  36.     ~htree(){  
  37.         destroy(root);  
  38.     }  
  39.     //pre_order_iterator  
  40.     class iterator{  
  41.     public:  
  42.         iterator()  
  43.             : _node(0)  
  44.             , skip_current_children_(false)  
  45.         {  
  46.             skip_children();  
  47.         }  
  48.         iterator(tree_node *node)  
  49.             : _node(node)  
  50.             , skip_current_children_(false)  
  51.         {  
  52.             skip_children();  
  53.         }  
  54.         ~iterator()  
  55.         {}  
  56.         T& operator*() const  
  57.         {  
  58.             return _node->name;  
  59.         }  
  60.         T* operator->() const  
  61.         {  
  62.             return &(_node->name);  
  63.         }  
  64.         tree_node* get()  
  65.         {  
  66.             return _node;  
  67.         }  
  68.         //开始位置  
  69.         iterator begin() const  
  70.         {  
  71.             return iterator(_node);  
  72.         }  
  73.         //结束位置  const????  
  74.         iterator end() const  
  75.         {  
  76.             return iterator( _find_end(_node) );  
  77.         }  
  78.           
  79.         tree_node *_node;  
  80.     protected:  
  81.         bool skip_current_children_;  
  82.         void         skip_children()  
  83.         {  
  84.             skip_current_children_=true;  
  85.         }  
  86.         tree_node* _find_end(tree_node* current) const  
  87.         {  
  88.             int pos = current->children.size()-1;  
  89.             if( pos<0 )  
  90.                 return (current);  
  91.                 //这里返回iterator会被析构掉,临时对象  
  92.             //从最后一个孩子找起,  
  93.             else  
  94.                 _find_end(current->children[pos]);  
  95.         }  
  96.     };  
  97. public:  
  98.     //注意传position的引用  
  99.     iterator insert(iterator& position, const T& x)       
  100.     {  
  101.         tree_node *tmp = new tree_node(x);  
  102.         position._node->children.push_back(tmp);  
  103.         tmp->parent = position._node;  
  104.         return iterator(tmp);  
  105.     }  
  106.     //后序递归输出  
  107.     void post_recurs_render(tree_node* some, unsigned recurs_level)  
  108.     {  
  109.         for (unsigned i = 0; i < some->children.size(); i++)  
  110.             post_recurs_render(some->children[i], recurs_level+1);  
  111.         for (int i = 0; i<recurs_level; i++)  
  112.             cout << "  ";  
  113.         cout << some->name << endl;  
  114.     }  
  115.     //先序递归输出  
  116.     void pre_recurs_render(tree_node* some, unsigned recurs_level)  
  117.     {  
  118.         for (int i = 0; i<recurs_level; i++)  
  119.             cout << "  ";  
  120.         cout << some->name << endl;  
  121.         for (unsigned i = 0; i < some->children.size(); i++)  
  122.             pre_recurs_render(some->children[i], recurs_level+1);  
  123.     }  
  124.   
  125.     //利用stack  
  126.     //使用Transform格式化输出  
  127.     void recurs_render(tree_node* some)  
  128.     {  
  129.         std::string temp;  
  130.         temp = form_stack.top() + some->format;  
  131.         form_stack.push(temp);  
  132.           
  133.         cout << temp;  
  134.         cout << some->name;  
  135.         cout << endl;  
  136.         for (unsigned i = 0; i < some->children.size(); i++)  
  137.             recurs_render(some->children[i]);  
  138.         form_stack.pop();  
  139.     }  
  140.     tree_node *root;  
  141. private:  
  142.     void Init(){  
  143.         form_stack.push(std::string(" "));  
  144.     };  
  145.     void destroy(tree_node *some)  
  146.     {  
  147.         #define SAFE_DELETE(p) {if(p){delete p; p=NULL;}}  
  148.         //后序删除  
  149.         for (unsigned i = 0; i < some->children.size(); i++)  
  150.             destroy(some->children[i]);  
  151.         SAFE_DELETE(some);  
  152.     }  
  153.     std::stack<std::string> form_stack;  
  154. };  
 

 

下面是main函数里的测试代码:

  1. int main()   
  2. {   
  3.     //for detecting the memory leaks  
  4.     int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );   
  5.     tmpFlag |= _CRTDBG_LEAK_CHECK_DF;   
  6.     _CrtSetDbgFlag( tmpFlag );  
  7.     typedef htree_node<string> node_type;  
  8.     typedef htree<string> tree_type;  
  9.     node_type *one = new node_type("one");  
  10.       
  11.     tree_type::iterator iter(one);  
  12.     tree_type tr1(one);  
  13.     tree_type::iterator two = tr1.insert(iter, "two");  
  14.     tree_type::iterator three = tr1.insert(iter, "three");  
  15.     tr1.insert(two, "apple");  
  16.     tr1.insert(two, "banana");  
  17.     tr1.insert(two, "peach");  
  18.     tr1.insert(three, "china");  
  19.     tr1.insert(three, "england");  
  20.       
  21.     //method 1:  
  22.     tr1.recurs_render(tr1.root);  
  23.     cout << "--------" << endl;  
  24.       
  25.     //method 2:   
  26.     tr1.pre_recurs_render(tr1.root, 1);  
  27.     cout << "--------" << endl;  
  28.     //method 3:  
  29.     tr1.post_recurs_render(tr1.root, 1);  
  30.     cout << "--------" << endl;  
  31.     // test iterator::end() function  
  32.     cout << (* (iter.end()) ) << endl;  
  33.     return 0;  
  34. }   
  

 

最终输出结果:

  1.    one  
  2.      two  
  3.        apple  
  4.        banana  
  5.        peach  
  6.      three  
  7.        china  
  8.        england  
  9. --------  
  10.   one  
  11.     two  
  12.       apple  
  13.       banana  
  14.       peach  
  15.     three  
  16.       china  
  17.       england  
  18. --------  
  19.       apple  
  20.       banana  
  21.       peach  
  22.     two  
  23.       china  
  24.       england  
  25.     three  
  26.   one  
  27. --------  
  28. england  

 



C++树的实现

STL里面没有提供容器树的模板实现,自已写一个:
Tree.h

  1. //tree.h 头文件    
  2.      
  3. #include <list>    
  4. #include <algorithm>    
  5. using namespace std;    
  6.      
  7. struct TreeNode; //定义一个结构体原型    
  8. classTree;      //定义一个类原型    
  9. classIterator; //定义一个类原型    
  10. typedef list<TreeNode*> List; //重命名一个节点链表    
  11.      
  12. TreeNode* clone(TreeNode*,List&,TreeNode*);//Clone复制函数    
  13.      
  14. struct TreeNode{   
  15.    int_data;                  //数据   
  16.    TreeNode* _parent;          //父节点   
  17.    List_children;             //子节点   
  18.    TreeNode(int,TreeNode*);    //构造函数   
  19.    void SetParent(TreeNode&); //设置父节点   
  20.    void InsertChildren(TreeNode&); //插入子节点   
  21. };    
  22.      
  23. classTree{   
  24. public:   
  25.     
  26.  //下面是构造器和运算符重载   
  27.    Tree();                            //默认构造函数   
  28.    Tree(constTree&);                 //复制构造函数   
  29.    Tree(constint);                   //带参数构造函数   
  30.    Tree(constint,constlist<Tree*>&);//带参数构造函数   
  31.    ~Tree();                           //析构函数   
  32.    Tree& operator=(constTree&);      //=符号运算符重载   
  33.    bool operator==(constTree&);      //==符号运算符重载   
  34.    bool operator!=(constTree&);      //!=符号运算符重载   
  35.     
  36.    //下面是成员函数   
  37.    void Clear();                      //清空   
  38.    boolIsEmpty()const;               //判断是否为空   
  39.    intSize()const;                   //计算节点数目   
  40.    intLeaves();                      //计算叶子数   
  41.    intRoot()const;                   //返回根元素   
  42.    intHeight();                      //计算树的高度   
  43.     
  44.     
  45.    //下面是静态成员函数   
  46.   static boolIsRoot(Iterator);     //判断是否是根   
  47.    static boolisLeaf(Iterator);     //判断是否是叶子   
  48.    static IteratorParent(Iterator); //返回其父节点   
  49.    static intNumChildren(Iterator); //返回其子节点数目   
  50.     
  51.    //跌代器函数   
  52.    Iteratorbegin();                  //Tree Begin   
  53.    Iteratorend();                    //Tree End   
  54.    friend classIterator;             //Iterator SubClass   
  55. private:   
  56.    list<TreeNode*> _nodes;         //节点数组   
  57.    list<TreeNode*>::iteratorLIt; //一个节点迭代器   
  58.    intheight(TreeNode*);   
  59.    intlevel(TreeNode*,Iterator);   
  60. };    
  61.      
  62. //This is TreeSub Class Iterator    
  63. classIterator{   
  64.    private:    
  65.     Tree* _tree;                     //Tree data   
  66.     list<TreeNode*>::iterator_lit; //List Iterator   
  67.    public:   
  68.     Iterator();                               //默认构造函数   
  69.     Iterator(constIterator&);                //复制构造函数   
  70.     Iterator(Tree*,TreeNode*);                //构造函数   
  71.     Iterator(Tree*,list<TreeNode*>::iterator);//构造函数   
  72.     //运算符重载   
  73.     void operator=(constIterator&);          //赋值运算符重载   
  74.     bool operator==(constIterator&);         //关系运算符重载   
  75.     bool operator!=(constIterator&);         //关系运算符重载   
  76.     Iterator& operator++();                   //前缀++运算符   
  77.     Iterator operator++(int);                 //后缀++运算符   
  78.     int operator*()const;                     //获得节点信息   
  79.     bool operator!();                         //赋值运算符重载   
  80.       
  81.     typedef list<TreeNode*>::iteratorList;   
  82.     friend classTree;   
  83. };    
 

 

Tree.cpp

  1. //tree.cpp 实现文件  
  2. #include "Tree.h"  
  3.    
  4. //***** 下面是对于TreeNode结构体的定义实现*****///  
  5.    
  6. TreeNode::TreeNode(inttype= 0,TreeNode* Parent = 0){ 
  7.  _data = type; 
  8.  _parent = Parent; 
  9. }  
  10. void TreeNode::SetParent(TreeNode& node){ 
  11.  _parent = &node; 
  12. }  
  13. void TreeNode::InsertChildren(TreeNode& node){ 
  14.  TreeNode* p = &node; 
  15.  _children.push_back(p); 
  16. }  
  17.    
  18. //***** 下面是对于Tree类的定义实现*****///  
  19. Tree::Tree(){ 
  20.   
  21. }  
  22.    
  23. Tree::Tree(constinttype){ 
  24.  _nodes.push_back(new TreeNode(type)); 
  25. }  
  26.    
  27. Tree::Tree(constTree& t){ 
  28.  if(t._nodes.empty())return; 
  29.  clone(t._nodes.front(),_nodes,0); 
  30. }  
  31. Tree::Tree(constinttype,constlist<Tree*>& lit){ 
  32.  TreeNode* root = new TreeNode(type);//建立根节点 
  33.  _nodes.push_back(root);//放入树中 
  34.  list<Tree*>::const_iteratorit; 
  35.  for(it = lit.begin();it!=lit.end();it++){ 
  36.  if(!((*it)->_nodes.empty())){//如果当前节点元素不为空 
  37.    Tree* tp = newTree(**it); 
  38.    TreeNode* p = tp->_nodes.front(); 
  39.    root->_children.push_back(p); //设置根的子节点 
  40.    p->_parent = root;            //设置节点的父节点为根 
  41.    list<TreeNode*>::iteratorlit1 = tp->_nodes.begin(); 
  42.    list<TreeNode*>::iteratorlit2 = tp->_nodes.end(); 
  43.    list<TreeNode*>::iteratorlit3 = _nodes.end(); 
  44.    _nodes.insert(lit3,lit1,lit2); 
  45.  }  
  46.  }  
  47. }  
  48.    
  49. Tree::~Tree(){ 
  50.  for(list<TreeNode*>::iteratorit = _nodes.begin();it!=_nodes.end();it++){ 
  51.  delete* it; 
  52.  }  
  53. }  
  54.    
  55. Tree& Tree::operator =(constTree & t){ 
  56.  Clear(); 
  57.  Tree* p = newTree(t); 
  58.  _nodes = p->_nodes; 
  59.  return *this; 
  60. }  
  61.    
  62. boolTree::operator ==(constTree& t){ 
  63.  if(_nodes.size()!=t._nodes.size()){ 
  64.  return false; 
  65.  }  
  66.  list<TreeNode*>::iteratorit = _nodes.begin();  
  67.  list<TreeNode*>::const_iterator_it = t._nodes.begin();  
  68.  while(it!=_nodes.end()&&_it!=t._nodes.end()){ 
  69.  if((*it)->_data!=(*_it)->_data){ 
  70.    return false; 
  71.  }  
  72.  it++;  
  73.  _it++;  
  74.  }  
  75.  return true;  
  76. }  
  77.    
  78. boolTree::operator !=(constTree& t){ 
  79.  if(_nodes.size()!=_nodes.size()){ 
  80.  return true; 
  81.  }  
  82.  else{ 
  83.  list<TreeNode*>::iteratorit = _nodes.begin(); 
  84.      list<TreeNode*>::const_iterator_it = t._nodes.begin(); 
  85.  while(it!=_nodes.end()&&_it!=t._nodes.end()){ 
  86.    if((*it)->_data!=(*_it)->_data){ 
  87.     return true; 
  88.    }  
  89.    it++;  
  90.    _it++;  
  91.  }  
  92.  return false;  
  93.  }  
  94. }  
  95.    
  96. void Tree::Clear(){ 
  97.  for(list<TreeNode*>::iteratorit = _nodes.begin();it!=_nodes.end();it++){ 
  98.  delete* it; 
  99.  }  
  100.  _nodes.clear();  
  101. }  
  102.    
  103. boolTree::IsEmpty()const{ 
  104.  return _nodes.empty(); 
  105. }  
  106.    
  107. intTree::Size()const{ 
  108.  return (int)_nodes.size(); 
  109. }  
  110.    
  111. intTree::Leaves(){ 
  112.  inti = 0; 
  113.  list<TreeNode*>::iteratorit = _nodes.begin(); 
  114.  while(it!=_nodes.end()){ 
  115.  if((*it)->_children.size()==0){ 
  116.    i++; 
  117.  }  
  118.  it++;  
  119.  }  
  120.  return i;  
  121. }  
  122.    
  123.    
  124. intTree::Height(){ 
  125.  if(_nodes.size()!=0){ 
  126.  TreeNode* TNode = _nodes.front(); 
  127.  return height(TNode); 
  128.  }  
  129.  else{ 
  130.  return -1; //判断为空树 
  131.  }  
  132. }  
  133.    
  134. intTree::height(TreeNode* node){ 
  135.  if(!node){ 
  136.  return -1; 
  137.  }  
  138.  else{ 
  139.  list<TreeNode*> plist = node->_children; 
  140.  if(plist.size()==0){ 
  141.    return 0; 
  142.  }  
  143.  inthA = 0;  
  144.  for(list<TreeNode*>::iteratorit = plist.begin();it!=plist.end();it++){ 
  145.   inthB = height(*it); 
  146.    if(hB>hA){ 
  147.     hA = hB; 
  148.    }  
  149.  }  
  150.  return hA+1;  
  151.  }  
  152. }  
  153.    
  154.    
  155. IteratorTree::begin(){ 
  156.  return Iterator(this,_nodes.begin()); 
  157. }  
  158.    
  159. IteratorTree::end(){ 
  160.  return Iterator(this,_nodes.end()); 
  161. }  
  162. intTree::Root()const{ 
  163.  return (*_nodes.begin())->_data; 
  164. }  
  165.    
  166.    
  167. boolTree::IsRoot(Iteratorit){ 
  168.  TreeNode p = *it; 
  169.  if(p._parent == 0){ 
  170.  return true; 
  171.  }  
  172.  return false;  
  173. }  
  174.    
  175. boolTree::isLeaf(Iteratorit){ 
  176.  TreeNode p = *it; 
  177.  if(p._children.size() == 0){ 
  178.  return true; 
  179.  }  
  180.  return false;  
  181. }  
  182.    
  183. IteratorTree::Parent(Iteratorit){ 
  184.  TreeNode p = *it; 
  185.  Tree* t = it._tree; 
  186.  IteratorIte(t,p._parent); 
  187.  return Ite; 
  188. }  
  189.    
  190.    
  191. intTree::NumChildren(Iteratorit){ 
  192.  TreeNode p = *it; 
  193.  return (int)p._children.size(); 
  194. }  
  195.    
  196. //***** 下面是对于Tree::Iterator类的定义实现*****///  
  197. Iterator::Iterator(){ 
  198. }  
  199.    
  200. Iterator::Iterator(constIterator& it){ 
  201.  _tree = it._tree; 
  202.  _lit = it._lit; 
  203. }  
  204.    
  205. Iterator::Iterator(Tree* t, TreeNode* n){ 
  206.  _tree = t; 
  207.  list<TreeNode*>& nodes = _tree->_nodes; 
  208.  _lit = find(nodes.begin(),nodes.end(),n);//<algorithm> Members 
  209. }  
  210.    
  211. Iterator::Iterator(Tree * t, list<TreeNode*>::iteratorlt){ 
  212.  _tree = t; 
  213.  _lit = lt; 
  214. }  
  215.    
  216. void Iterator::operator =(constIterator& it){ 
  217.  _tree = it._tree; 
  218.  _lit = it._lit; 
  219. }  
  220.    
  221. boolIterator::operator ==(constIterator & it){ 
  222.  return _tree == it._tree && _lit == it._lit; 
  223. }  
  224.    
  225. boolIterator::operator !=(constIterator & it){ 
  226.  return _tree != it._tree || _lit != it._lit; 
  227. }  
  228.    
  229. Iterator& Iterator::operator ++(){ 
  230.  ++_lit; 
  231.  return *this; 
  232. }  
  233.    
  234. IteratorIterator::operator ++(int){ 
  235.  Iteratorit(*this); 
  236.  ++_lit; 
  237.  return it; 
  238. }  
  239.    
  240. intIterator::operator *() const{ 
  241.  return ((*_lit)->_data); 
  242. }  
  243.    
  244. boolIterator::operator !(){ 
  245.  return _lit == _tree->_nodes.end(); 
  246. }  
  247.    
  248. //Clone函数  
  249. TreeNode* clone(TreeNode* node,List& nodes,TreeNode* nodep){ 
  250.  TreeNode* cp = new TreeNode(node->_data,nodep); 
  251.  nodes.push_back(cp); 
  252.  List& l = node->_children; 
  253.  List& cl = cp->_children; 
  254.  for(list<TreeNode*>::iteratorlt = l.begin();lt!=l.end();lt++){ 
  255.  cl.push_back(clone(*lt,nodes,cp)); 
  256.  }  
  257.  return cp;  
  258. }  

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多