线索二叉树,二叉搜索树的简单实现

利用前面的二叉树设计,可以很方便的实现线索二叉树,二叉搜索树,下面给出代码,很多功能还有待添加。
//thread_binary_tree.h
  1  #ifndef _THREAD_BIANTY_TREE_H_
  2  #define  _THREAD_BIANTY_TREE_H_
  3 
  4  #include  " binary_tree.h "
  5 
  6  namespace  binary_tree{
  7 
  8  // ThreadBinaryTreeNode with elem type T
  9  template < typename T >
 10  class  ThreadBinaryTreeNode :  public  BinaryTreeNodeBase <  T, ThreadBinaryTreeNode < T >   >  {
 11       public :
 12          typedef with_thread_node_tag node_category;
 13          ThreadBinaryTreeNode() :m_ltag( 0 ),m_rtag( 0 ) {}
 14          ThreadBinaryTreeNode( const  T &  elem, ThreadBinaryTreeNode < T >   *  left  =  NULL, 
 15                               ThreadBinaryTreeNode < T >   *  right  =  NULL,
 16                                bool  ltag  =   0 bool  rtag  =   0 )
 17                  : BinaryTreeNodeBase <  T, ThreadBinaryTreeNode < T >   >  (elem, left, right), 
 18                    m_ltag(ltag), m_rtag(rtag){}
 19           const   bool  ltag()  const {
 20               return  m_ltag;
 21          }
 22           const   bool  rtag()  const {
 23               return  m_rtag;
 24          }
 25           void  set_ltag( bool  ltag){
 26              m_ltag  =  ltag;
 27          }
 28           void  set_rtag( bool  rtag){
 29              m_rtag  =  rtag;
 30          }
 31       private :
 32           bool  m_ltag;
 33           bool  m_rtag;
 34  };
 35 
 36  template  < typename U, typename T  =  ThreadBinaryTreeNode < U >   >
 37  class  ThreadBinaryTree;
 38 
 39  // 到底要不要让穿线二叉树继承BinaryTree呢还是独立一个类
 40  // 如果继承,那么要继承所有接口,但是基本上都要重写内容
 41  // 我现在只关心一部分内容,提供一部分接口,所以可以独立
 42  // 写,这里还是用了继承先,注意使用的时候仅使用那些穿线二叉
 43  // 树改写的内容的接口,理论上一个完整的穿线二叉树应该能
 44  // 提供BinaryTree的所有接口的,而且这样好复用简单
 45  // 也可以单独一个类,以后如果需要添加其它接口,需要BinaryTree
 46  // 的实现的化用复合,调用处理。
 47  // 其实如ThreadBinaryTree只想继承BinaryTree的一部分,暗示
 48  // BinaryTree的接口太多了,想要继承的是核心接口,应该提出来。
 49  // 剩下的可以AdvacedBinaryTree public BinaryTree
 50  // 或者剩下的用non memer func
 51  // 这里先用private 继承 屏蔽掉基类的接口,恩还是可以用复用
 52  // 但是复用代码写起来麻烦些,哦但是那样基类的root()
 53  // 用户也没办法用了,还要在thread_tree中明写,权衡,呵呵
 54  // 暂时还是public吧, TODO
 55 
 56  // 注意对于PrintTree采用了InorderTravel(虚函数重定义)不同的基类triats手法
 57  template  < typename U >
 58  class  ThreadBinaryTree <  U,ThreadBinaryTreeNode < U >   >  :  public  BinaryTree < U, ThreadBinaryTreeNode < U >   >  {
 59       public :
 60          typedef ThreadBinaryTreeNode < U >  T;
 61           ~ ThreadBinaryTree() { DeleteBinaryTree( this -> root());  this -> set_root(NULL); }  // well 无法访问需要 this->
 62           virtual   void  DeleteBinaryTree(T  * root);
 63           virtual   void  InOrderTravel(T  * root);
 64           virtual   void  CreateTree(U end_mark) {
 65              BinaryTree < U, ThreadBinaryTreeNode < U >   > ::CreateTree(end_mark);
 66               // T* p = NULL;
 67               // InThreadRec(this->root(), p);    // no access to m_root directly, 注意InThreadRec(this->root(), NULL)不对
 68              InThreadNoRec( this -> root());
 69              cout  <<   " Finished inorder threading "   <<  endl;
 70          }
 71           //  TODO
 72  //         virtual void FindElem(T* root, U elem);
 73  //         virtual void PrintTree();  // 涉及很多地方要改动
 74  //         virtual void PreOrderTravel();
 75  //         virtual void PostOrderTravel();
 76  //         T* InOrderNext(T *current);
 77  //         T* InOrderPre(T *current);
 78  //         T* PreOrderNext(T *current);
 79  //         void InsertNode(T *pointer, T *newpointer)
 80       private :
 81           // 递归中序线索化二叉树
 82           void  InThreadRec(T  * root, T  *& pre);      // 这里需要引用.wow!,这里的pre相当一个全局量,而不是随着递归变化的,相当sum
 83           // 非递归中序线索化二叉树                 // 相当容易出错!!!因为要求pre的值及时变化,但如果不是引用,下层变化了,退
 84           void  InThreadNoRec(T  * root);             // 到上层,pre的值又变回到当时的值了(当前栈内)
 85           // 中序周游
 86  };
 87 
 88  template  < typename U >
 89  void  ThreadBinaryTree <  U,ThreadBinaryTreeNode < U >   >  ::
 90  DeleteBinaryTree(ThreadBinaryTreeNode < U >   * root) {
 91      cout  <<   " Dlete thread tree "   <<  endl;
 92       if  (root) {
 93           if  ( ! root -> ltag())
 94              DeleteBinaryTree(root -> left());
 95           if  ( ! root -> rtag())
 96              DeleteBinaryTree(root -> right());
 97          delete root;
 98      }
 99  }
100  // 关于二叉中序穿线树就是对于左子树为空的存它在中序遍历的前驱,显然对于中序第一访问的节点没有前驱,这里采用不处理方式
101  // 是不行的,因为遍历的时候不方便,也需要把它设置为ltag = 1;
102  // 右子树为空则存它在中序遍历的后继,对于中序最后访问的节点,无后继,不特殊处理,所以最后存在两个NULL指针
103  // 对于NULL指针也就无所谓去判断是线索还是左右子树了。
104  template  < typename U >
105  void  ThreadBinaryTree <  U,ThreadBinaryTreeNode < U >   >  ::
106  InThreadRec(ThreadBinaryTreeNode < U >   * root, ThreadBinaryTreeNode < U >   *& pre) {
107      cout  <<   " Inorder rec threading "   <<  endl;
108       if  (root) {
109          InThreadRec(root -> left(), pre);
110           if  ( ! root -> left()) {
111              root -> set_ltag( 1 );
112              root -> set_left(pre);        
113          }
114           if  (pre  &&   ! pre -> right()) {
115              pre -> set_rtag( 1 );
116              pre -> set_right(root);
117          }
118          pre  =  root;
119          InThreadRec(root -> right(), pre);
120      }
121  }
122 
123  template  < typename U >
124  void  ThreadBinaryTree <  U,ThreadBinaryTreeNode < U >   >  ::
125  InThreadNoRec(ThreadBinaryTreeNode < U >   * root) {
126      cout  <<   " Inorder threading no rec "   <<  endl;
127      typedef ThreadBinaryTreeNode < U >  T;
128      T *  p  =  root;
129      T *  pre  =  NULL;
130      stack < *>  s;
131       while ( ! s.empty()  ||  p) {
132           if  (p){
133              s.push(p);
134              p  =  p -> left();
135          }  else  {
136              p  =  s.top();
137               if  ( ! p -> left()) {
138                  p -> set_ltag( 1 );                   
139                  p -> set_left(pre);
140              }
141               if  (pre  &&   ! pre -> right()) {
142                  pre -> set_rtag( 1 );
143                  pre -> set_right(p);
144              }
145              pre  =  p;
146              s.pop();
147              p  =  p -> right();
148          }
149      }
150  }
151 
152  template  < typename U >
153  void  ThreadBinaryTree <  U,ThreadBinaryTreeNode < U >   >  ::
154  InOrderTravel(ThreadBinaryTreeNode < U >   * root) {
155      cout  <<   " Inorder travel thread tree "   <<  endl;
156      typedef ThreadBinaryTreeNode < U >  T;
157      T *  p  =  root;
158  //     while (p) {
159  //         if (!p->ltag()) { 
160  //             p = p->left();
161  //         } else {
162  //             Visit(p);
163  //             while (p->rtag()) {
164  //                 p = p->right();
165  //                 Visit(p);
166  //             }
167  //             p = p->right();      // 上面的while 是必要的 不能直接p->right 只有对于原右子为空情况p->right 才进入下一向左状态
168  //         }                        // 否则p->right 之后右p->left重复访问左子树了
169  //     }
170       while  (p) {
171           while ( ! p -> ltag()) { 
172              p  =  p -> left();           // 左子树走
173          } 
174          Visit(p);                   // 访问
175           while  (p -> rtag()) {         // 右子树为空,相当不停的pop 访问根节点(左子树已经访问完)
176              p  =  p -> right();         // 注意p->right 访问后继的话,证明左子树访问完,要访问右子的,没有继续后继,而不能重复再访问左子
177              Visit(p);
178          }
179          p  =  p -> right();        // OK,进入右子树,重复开始的向左走
180      }                          // 上面的while 是必要的 不能直接p->right 只有对于原右子为空情况p->right 才进入下一向左状态
181  }                              // 否则p->right 之后右p->left重复访问左子树了
182 
183 
184 
185  // template <typename U, typename T = ThreadBinaryTreeNode<U> >
186  // class ThreadBinaryTree {
187  //     public:
188  //         ThreadBinaryTree() { m_root = NULL;}
189  //         virtual ~ ThreadBinaryTree() {DeleteBinaryTree(m_root);}
190  //     private:
191  //         T* m_root;
192  // }
193 
194 
195  }    //  end of namespace binary_tree
196  #endif   //  end of _THREAD_BIANTY_TREE_H_
197 
//binary_search_tree.h
  1  #ifndef _BINARY_SEARCH_TREE_H_
  2  #define  _BINARY_SEARCH_TREE_H_ 
  3  #include  " binary_tree.h "
  4  namespace  binary_tree{
  5 
  6  // 当期二叉搜索树无重复值节点
  7  template < typename U, typename T  =  BinaryTreeNode < U >   >
  8  class  BinarySearchTree;
  9 
 10  //  TODO 这个命名不太好
 11  //  允许有重复元素的二叉搜索树
 12  template < typename U, typename T  =  BinaryTreeNode < U >   >
 13  class  BinarySearchTree2;
 14 
 15  template < typename U >
 16  class  BinarySearchTree <  U, BinaryTreeNode < U >   >  :  public  BinaryTree <  U, BinaryTreeNode < U >   >  {
 17       public :
 18          typedef BinaryTreeNode < U >  T;
 19           //  TODO why here do not need 构造函数,while BinaryTree need
 20           void  InsertNode( const  U elem) {
 21               // InsertNodeRec(this->m_root, elem);
 22              InsertNode( this -> m_root, elem);
 23          }
 24           void  DeleteNode( const  U elem) {
 25              DeleteNode( this -> m_root, elem);
 26          }
 27       private :
 28           void  InsertNodeRec(T  *& root, const  U elem);
 29           virtual   void  InsertNode(T  * root,  const  U elem);
 30           virtual   void  DeleteNode(T  * root,  const  U elem);
 31           // void InsertNode(T *root, T *pn);
 32  };
 33 
 34  // 允许相同的元素,后进入的相同元素插入到原元素右子树的最左下
 35  // well 这里有个问题,对于继承类,
 36  // 例如 BinarySearchTre2<float> tree; tree.InserNode(3.0);  
 37  // 编译器似乎只会找到 InsertNode(T *root, const U elem),认为它最匹配但不成功
 38  // 而不会去基类中查找,解决办法避免重名重载?
 39  //  TODO 这里先把虚函数名从 InsertNode改成InsertNode成功 不过感觉不爽
 40  //  well 条款33,基类的名称被遮掩了!!所以编译器看不到基类的void InsertNode(const U elem)
 41  //  这个陷阱好深,其实编译器应该对子类的虚函数不要掩盖基类名称.
 42  //  另外编译器竟然还是要求virtual void DeleteNode(T *root, const U elem)
 43  //  提供定义,不能用基类默认的吗,哦,用默认的你就不要再写
 44  template < typename U >
 45  class  BinarySearchTree2 < U, BinaryTreeNode < U >   >  :  public  BinarySearchTree < U, BinaryTreeNode < U >   >  {
 46       public :
 47          typedef BinaryTreeNode < U >  T;
 48           // 这样也不行,因为基类有个virtual void InsertNode(T *root, const U elem);是私有
 49           // using  BinarySearchTree<U, BinaryTreeNode<U> >::InsertNode;
 50           // 这能用转交函数了,或者你就改名 呵呵
 51           void  InsertNode( const  U elem) {
 52              BinarySearchTree < U, BinaryTreeNode < U >   > ::InsertNode(elem);
 53          }
 54           // 递归函数打印min到mx之间的元素
 55           void  PrintRange(T  * root, U min, U max);
 56           int  PrintRangeRec(T  * root, U min, U max);
 57       private :
 58           virtual   void  InsertNode(T  * root,  const  U elem);
 59           // virtual void DeleteNode(T *root, const U elem);
 60  };
 61 
 62  /* binary tree 实现 */
 63 
 64  // 递归写法,简单,但是注意到每次只可能走一个分支,其实递归是没有意义的
 65  // 可以很简单的写成非递归
 66  template  < typename U >
 67  void  BinarySearchTree <  U,BinaryTreeNode < U >   > ::
 68  InsertNodeRec(BinaryTreeNode < U >   *& root, const  U elem) {
 69      typedef BinaryTreeNode < U >  T;
 70       if  ( ! root)
 71          root  =   new  T(elem);
 72       else   if  (elem  <  root -> elem())
 73          InsertNode(root -> m_left, elem);
 74       else   if  (elem  >  root -> elem())
 75          InsertNode(root -> m_right, elem);
 76       else     // 遇到相同节点,不需要插入
 77           return ;
 78  }
 79 
 80  // So 不要递归思维定势
 81  template  < typename U >
 82  void  BinarySearchTree <  U,BinaryTreeNode < U >   > ::
 83  InsertNode(BinaryTreeNode < U >   * root, const  U elem) {
 84      typedef BinaryTreeNode < U >  T;
 85       // 空树
 86       if  ( ! root) {
 87           this -> set_root( new  T(elem));
 88           return ;
 89      }
 90 
 91      T *  p  =  root;
 92      
 93       while  ( 1 ) {
 94           if  (elem  ==  p -> elem())       // 遇到相同的节点,无需插入了
 95              break
 96           if  (elem  <  p -> elem()) { 
 97               if  (p  -> left()) {
 98                  p  =  p -> left();
 99              }  else  {
100                  p -> set_left( new  T(elem));
101                   break ;
102              }
103 
104          }  else  {
105               if  (p -> right()) {
106                  p  =  p -> right();
107              }  else  { 
108                  p -> set_right( new  T(elem));
109                   break ;
110              }
111          }
112      }
113  }
114  template  < typename U >
115  void  BinarySearchTree <  U,BinaryTreeNode < U >   > ::
116  DeleteNode(BinaryTreeNode < U >   * root, const  U elem) {
117      typedef BinaryTreeNode < U >  T;
118      
119       if ( this -> IsEmpty())
120           return ;
121       
122  }
123 
124 
125  /* 带重复元素的binary tree实现 */
126 
127  template  < typename U >
128  void  BinarySearchTree2 <  U,BinaryTreeNode < U >   > ::
129  InsertNode(BinaryTreeNode < U >   * root, const  U elem) {
130      typedef BinaryTreeNode < U >  T;
131       // 空树
132       if  ( ! root) {
133           this -> set_root( new  T(elem));
134           return ;
135      }
136      T *  p  =  root;
137       while  ( 1 ) {
138           if  (elem  <  p -> elem()) { 
139               if  (p  -> left()) {
140                  p  =  p -> left();
141              }  else  {
142                  p -> set_left( new  T(elem));
143                   break ;
144              }
145 
146          }  else  {     //  elem >= p->elem()
147               if  (p -> right()) {
148                  p  =  p -> right();
149              }  else  { 
150                  p -> set_right( new  T(elem));
151                   break ;
152              }
153          }
154      }
155  }
156 
157  template  < typename U >
158  void  BinarySearchTree2 <  U,BinaryTreeNode < U >   > ::
159  PrintRange(BinaryTreeNode < U >   * root, U min, U max) {
160      assert(min  <=  max);
161      typedef BinaryTreeNode < U >  T;
162       if  ( ! root)
163           return ;
164       if  (root -> elem()  ==  min) {    // 遇到了比min小或者相同的,其左子树无须访问了,相同需先访问根,小于则无需了直接右子树
165          Visit(root);
166          PrintRange(root -> right(),min,max);
167      }  else   if  (root -> elem()  >  min) {    
168          PrintRange(root -> left(),min,max);
169           if  (root -> elem()  >  max)   //  遇到更大的遍历结束
170               return ;
171          Visit(root);
172          PrintRange(root -> right(), root -> elem(), max);  // 改成root->elem()没有太大优化
173      }  else  {
174          PrintRange(root -> right(),min,max);
175      }
176  }
177 
178  template  < typename U >
179  int  BinarySearchTree2 <  U,BinaryTreeNode < U >   > ::
180  PrintRangeRec(BinaryTreeNode < U >   * root, U min, U max) {
181      
182  }
183 
184  }         // end of namespace binary_tree
185  #endif     // end of _BINARY_SEARCH_TREE_H_ 
186 

你可能感兴趣的:(二叉树)