二叉查找树_前序遍历_中序_后序_递归与非递归写法_层次遍历_以及树形显示

二叉查找树_前序遍历_中序_后序_递归与非递归写法_层次遍历_以及树形显示

  1 #include <iostream>
  2 #include <stack>
  3 using namespace std;
  4 
  5 template<typename T>
  6 struct BinaryNode
  7 {
  8     T element;
  9     BinaryNode<T> *left;
 10     BinaryNode<T> *right;
 11 
 12     BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt)
 13         : element(theElement), left(lt), right(rt) {}
 14 };
 15 
 16 
 17 template<typename T>
 18 class BinarySearchTree
 19 {
 20 public:
 21     BinarySearchTree() {
 22         root = nullptr;
 23     }
 24     BinarySearchTree(const BinarySearchTree& rhs) {  //复制构造函数
 25         root = clone(rhs.root);
 26     }
 27     ~BinarySearchTree();
 28 
 29     const T &findMin() const {
 30         return findMin(root)->element;
 31     }
 32     const T &findMax() const {
 33         return findMax(root)->element;
 34     }
 35     
 36     bool contains(const T& x) const;
 37     T& getNode(const T& e) {                        //得到元素为e的结点 
 38         return getNode(e, root)->element;
 39     }
 40     
 41     bool isEmpty() const {
 42         if (root == nullptr)
 43             return true;
 44         return false;
 45     }
 46     void PreprintTree() const {
 47         PreprintTree(root);
 48     }
 49     
 50     void InprintTree() const {
 51         InprintTree(root);
 52     }
 53     
 54     void PostprintTree() const {
 55         PostprintTree(root);
 56     }
 57     
 58     void LevelprintTree() const {
 59         LevelprintTree(root);
 60     }
 61     
 62     void PreprintTree_N() const {
 63         PreprintTree_N(root); 
 64     }
 65     
 66     void InprintTree_N() const {
 67         InprintTree_N(root);
 68     }
 69     
 70     void PostprintTree_N() const {
 71         PostprintTree_N(root);
 72     }
 73     
 74     void DisplayTreeShape(int level = 1) const {
 75         DisplayTreeShape(root, level);
 76     }
 77 
 78     void makeEmpty();
 79     void insert(const T &x);
 80     void remove(const T &x);
 81     int Depth(); 
 82     int CountLeaf() {
 83         BinaryNode<T> *p = root;
 84         int count = 0;
 85         CountLeaf(p, count);
 86         return count;
 87     }
 88     
 89     const BinarySearchTree& operator = (const BinarySearchTree& rhs);
 90 
 91 private:
 92 
 93     BinaryNode<T> *root;                      //指向树根结点的指针
 94 
 95     void insert(const T & x, BinaryNode<T> * & t);  
 96     void remove(const T & x, BinaryNode<T> * & t);
 97     BinaryNode<T> * findMin(BinaryNode<T> *t) const;
 98     BinaryNode<T> * findMax(BinaryNode<T> *t ) const;
 99     
100     bool contains(const T & x, BinaryNode<T> *t) const;
101     BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t);
102     
103     void makeEmpty( BinaryNode<T> * & t );                  
104     //利用 递归 算法 计算树的 深度 
105     int Depth( BinaryNode<T> * t, int level, int &depth);
106     //利用 递归 算法 计算树的 高度
107     void CountLeaf(BinaryNode<T> * t, int &count);
108     
109         
110     void PreprintTree( BinaryNode<T> * t ) const;           //先序遍历 
111     void InprintTree( BinaryNode<T> *t ) const;             //中序遍历   
112     void PostprintTree( BinaryNode<T> * t ) const;          //后序遍历
113     void LevelprintTree( BinaryNode<T> * t) const;          //层次遍历 
114     
115     void PreprintTree_N( BinaryNode<T> * t) const;          //非递归先序遍历
116     void InprintTree_N( BinaryNode<T> * t) const;           //非递归中序遍历二叉树 
117     void PostprintTree_N( BinaryNode<T> * t) const;         //非递归后序遍历二叉树 
118     void DisplayTreeShape(BinaryNode<T> *bt, int level) const;    //二叉树的树形显示算法 
119     
120       
121     BinaryNode<T> * clone( BinaryNode<T> * t ) const;
122 };
123 
124 template<typename T>
125 bool BinarySearchTree<T>::contains(const T& x) const
126 {
127     return contains(x, root);
128 }
129 
130 template<typename T>
131 bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const
132 {
133     if (t == nullptr)
134         return false;
135     else if (x < t->element)          // x 小, 说明应该在左边找
136         return contains(x, t->left);
137     else if (t->element < x)          // x 大, 说明应该在右面找
138         return contains(x, t->right);
139     else 
140         return true;
141 }
142 
143 template<typename T>
144 BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t)
145 {
146     if (t == nullptr) 
147         return nullptr;
148     else if (x < t->element)
149         return getNode(x, t->left);
150     else if (t->element < x)
151         return getNode(x, t->right);
152     return t;
153 }
154 
155 
156 //findMin--返回指向树中包含最小元的结点的指针
157 template<typename T>
158 BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const
159 {
160     if (t == nullptr)
161         return  nullptr;
162     if (t->left == nullptr)
163         return t;
164     return findMin(t->left);
165 }
166 
167 template<typename T>
168 BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const
169 {
170     if (t != nullptr)
171         while (t->right != nullptr) {
172             t = t->right;
173         }
174     return t;
175 }
176 
177 template<typename T>
178 void BinarySearchTree<T>::insert(const T &x)
179 {
180     insert(x, root);
181 }
182 
183 /************************************************************************/
184 /* x is the item to insert        */
185 /* t is the node that roots the subtree*/
186 /* Set the new root of the subtree*/
187 ///* 只有当一个新树叶生成时候,t才改变.
188 ///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点.
189 /************************************************************************/
190 template<typename T>
191 void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t)
192 {
193     if (t == nullptr)         //没有结点,在该位置处添加新结点
194         t = new BinaryNode<T>(x, nullptr, nullptr);
195     else if (x < t->element)  //x 小, 在左子树查询
196         insert(x, t->left);  
197     else if (t->element < x)  //x 大, 在右子树查询
198         insert(x, t->right);
199     else;                     //Duplicate, do nothing;
200 }
201 
202 template<typename T>
203 void BinarySearchTree<T>::remove(const T &x)
204 {
205     remove(x, root);
206 }
207 
208 /************************************************************************/
209 /* x is item to remove                                                  */
210 /* t is the node that roots the subtree                                 */
211 /* Set the new root of the subtree                                      */
212 /* 1.结点是一片树叶时 -- 可被立即删除*/
213 /* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */
214 /* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */
215 /* 注: 右子树中的最小的结点不可能有左结点                               */
216 /************************************************************************/
217 template<typename T>
218 void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t)
219 {
220     if (t == nullptr) return;     //Item not found; do nothing
221     if (x < t->element)           //x 小,在左子树递归查找
222         remove(x, t->left);
223     else if (t->element < x)      //x 大,在右子树递归查找
224         remove(x, t->right); 
225     else if (t->left != nullptr && t->right != nullptr)  //two children
226     {
227         //在右子树中查找最小数据代替该结点数据.;
228         t->element = findMin(t->right)->element;
229         remove(t->element, t->right);                    //删除该结点
230     }
231     else                         //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除.
232     {                          
233         BinaryNode<T> *oldNode = t;
234         t = (t->left != nullptr) ? t->left : t->right;
235         delete oldNode;
236     }
237 }
238 
239 /************************************************************************/
240 ///* Destructor for the tree
241 /************************************************************************/
242 template<typename T>
243 BinarySearchTree<T>::~BinarySearchTree()
244 {
245     makeEmpty();
246 }
247 
248 template<typename T>
249 void BinarySearchTree<T>::makeEmpty()       //公有函数
250 {
251     makeEmpty(root);
252 }
253 
254 /************************************************************************/
255 ///* Internal method to make subtree empty -- 私有函数
256 /************************************************************************/
257 template<typename T>
258 void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t)   
259 {
260     if (t != nullptr)
261     {
262         makeEmpty(t->left);
263         makeEmpty(t->right);
264         delete t;
265     }
266     t = nullptr;
267 }
268 
269 /************************************************************************/
270 ///* Deep copy
271 /************************************************************************/
272 template<typename T>
273 const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs)
274 {
275     if (this != &rhs) {
276         makeEmpty();
277         root = clone(rhs.root);
278     }
279     return *this;
280 }
281 
282 /************************************************************************/
283 ///* Internal method to clone subtree.  --  递归复制结点
284 /************************************************************************/
285 template<typename T>
286 BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const
287 {
288     if (t == nullptr)
289         return nullptr;
290     return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) );
291 }
292 
293 //利用递归计算树的深度 
294 template<typename T>
295 int BinarySearchTree<T>::Depth()
296 {
297     BinaryNode<T> *t = root;
298     int depth = 0;
299     if (root == nullptr) 
300         return 0;
301     Depth(t, 1, depth);
302     return depth;
303 }
304 
305 //由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度 
306 template<typename T>
307 int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth)
308 {
309     if (level > depth) depth = level;                  //层数
310     if (t->left) Depth(t->left, level + 1, depth);     //递归遍历左子树,且层数加1 
311     if (t->right) Depth(t->right, level + 1, depth);   //递归遍历右子树, 且层数加1 
312     return 0; 
313 }
314 
315 template<typename T>
316 //利用 递归 算法 计算树的 高度
317 void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count)
318 {
319     if (t == nullptr) return;               //为空时,退出
320 
321 //    CountLeaf(t->left, count);
322 //    CountLeaf(t->right, count); 
323     if (!(t->left) && !(t->right)) {        //儿子为空时 
324         count++;
325     }
326     CountLeaf(t->left, count);
327     CountLeaf(t->right, count); 
328 }
329 
330 
331 /************************************************************************/
332 ///* printTree   ---    前序遍历 
333 /************************************************************************/
334 template<typename T>
335 void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const
336 {
337     if (t != nullptr) {
338         cout << t->element << ' ';     
339         PreprintTree(t->left);
340         PreprintTree(t->right);
341     }
342 }
343 
344 //中序遍历 
345 template<typename T>
346 void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t ) const
347 {
348     if (t != nullptr) {
349         InprintTree(t->left);
350         cout << t->element << ' ';
351         InprintTree(t->right);
352     }    
353 } 
354 
355 //后序遍历 
356 template<typename T>
357 void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const 
358 {
359     if (t != nullptr) {
360         PostprintTree(t->left);
361         PostprintTree(t->right);
362         cout << t->element << ' ';
363     }    
364 }
365 
366 //利用队列Queue层次遍历二叉树 
367 template<typename T>
368 void BinarySearchTree<T>::LevelprintTree( BinaryNode<T> * t) const
369 {
370     const int maxn = 1024;
371     BinaryNode<T> *Queue[maxn];                          //一维数组作为队列 
372     BinaryNode<T> *tmp;                         
373     int front = 0, rear = 0;                             //队列初始为空 
374     if (root) {
375         Queue[rear++] = root;                            //二叉树的根结点指针入队列 
376         while (front != rear)
377         {
378             tmp = Queue[front++];                        //队首的元素出队列
379             if (tmp) cout << tmp->element << ' ';        //输出结点值
380             if (tmp->left) Queue[rear++] = tmp->left; 
381             if (tmp->right) Queue[rear++] = tmp->right; 
382         }
383     }
384 }
385 
386 //先序遍历 
387 template<typename T>
388 void BinarySearchTree<T>::PreprintTree_N( BinaryNode<T> * t) const          //非递归先序遍历
389 {
390     const int maxn = 1024;
391     BinaryNode<T> *Stack[maxn];    
392     int top = 0;
393     BinaryNode<T> *tmp = root;            //将根结点的指针赋值给tmp 
394     
395 //    cout << "Debug :\n";
396     while (tmp || top != 0)
397     {
398 //        cout << "debug : \n";
399         while (tmp) {
400             cout << tmp->element << ' ';
401             Stack[top++] = tmp;           //右孩子入栈 
402             tmp = tmp->left;              //一直递归到最左的结点 
403         }    
404         if (top) {                        //栈不为空, 从栈中取出一个结点指针 
405             tmp = Stack[--top];           
406             tmp = tmp->right;                   
407         }
408     }    
409 }
410 
411 //中序非递归遍历二叉树 (LDR)
412 template<typename T>
413 void BinarySearchTree<T>::InprintTree_N( BinaryNode<T> * t) const           //非递归中序遍历二叉树 
414 {
415     const int maxn = 1024;
416     BinaryNode<T> *Stack[maxn];
417     int top = 0;
418     BinaryNode<T> *tmp = root;
419     
420     while (tmp || top != 0)
421     {
422         while (tmp) {                  //迭代到最左的子树 
423             Stack[top++] = tmp;        //左子树入栈 
424             tmp = tmp->left;
425         }
426         if (top) {
427             tmp = Stack[--top];            //出栈最左的子树 
428             cout << tmp->element << ' ';   //输出该元素 
429             tmp = tmp->right;              //并指向右结点开始迭代 
430         }
431     }
432      
433 }
434 
435 //非递归后序遍历二叉树 (LRD)
436 template<typename T>
437 void BinarySearchTree<T>::PostprintTree_N( BinaryNode<T> * t) const         
438 {
439        const int maxn = 1024;
440     struct Mystack {
441         BinaryNode<T> * link;
442         int flag;
443     };
444     
445     Mystack Stack[maxn]; 
446     BinaryNode<T> * p = root, *tmp;
447 
448     if (root == nullptr) return;
449 
450     int top = -1,                  //栈顶初始化 
451         sign = 0;                  //为结点tmp 的标志量 
452     
453     while ( p != nullptr || top != -1)
454     {
455         while (p != nullptr)       //遍历到最左 
456         {
457             Stack[++top].link = p; //并且一直入栈 
458             Stack[top].flag = 1;   //设置flag为第一次入栈 
459             p = p->left;         
460         }        
461         
462         if (top != -1)         
463         {                          
464             tmp = Stack[top].link; 
465             sign = Stack[top].flag;
466             top--;                 //出栈 
467                                    
468             if (sign == 1)         //结点第一次进栈 
469             {
470                 top++;
471                 Stack[top].link = tmp;
472                 Stack[top].flag = 2;            //标记为第二次出栈 
473                 p = tmp->right;    
474             }
475             else {                 //第二次出栈就输出 
476                 cout << tmp->element << ' ';      //访问该结点数据域 
477                 p = nullptr;
478             }
479         }
480     
481     }
482     
483 }
484 
485 //树形显示二叉树,也是中序遍历 
486 template<typename T>
487 void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const
488 {    
489     if (bt)                                         //二叉树的树形显示算法
490     {
491         cout << endl;
492         for (int i = 0; i < level - 1; i++)         
493             cout << "   ";                            //确保在第level列显示结点 
494         cout << bt->element;                        //显示结点 
495         DisplayTreeShape(bt->left, level - 1);     //空二叉树不显示
496 //        cout << endl;                               //显示右子树
497         DisplayTreeShape(bt->right, level + 2);      //显示左子树 
498     } 
499 }
500 
501 int main()
502 {
503 //    srand((unsigned)time(nullptr));
504     int testData, t = 0;
505     BinarySearchTree<int> test;
506     cout << "输入数字个数: \n";
507     cin >> t;
508     cout << "输入数字: \n";
509     while (t--)
510     {
511         testData = rand() % 500 + 1;
512         test.insert(testData);
513     }
514     cout << "\n全部元素为: \n";
515     test.PreprintTree();
516     
517     cout << endl;
518 //    cin >> testData;                //不符合查找二叉树 
519 //    test.getNode(testData) = 10000;
520     
521     
522     cout << "\nMax = " << test.findMax() << endl;
523     cout << "Min = " << test.findMin() << endl;
524 
525     cout << "输入查找元素: \n";
526     cin >> testData;
527     cout << "是否包含 " << testData  << " : " << test.contains(testData) << endl; 
528     test.PreprintTree();
529     
530     cout << endl;
531     cout << "输入删除元素: \n";
532     cin >> testData;
533     test.remove(testData);
534     
535     cout << "\n树的高度: " << test.Depth() << endl;
536     cout << "\n叶子的个数: " << test.CountLeaf() << endl; 
537     cout << endl;
538     
539     cout << "先序遍历树元素: \n";
540     test.PreprintTree();
541     
542     cout << "\n\n中序遍历树元素: \n";
543     test.InprintTree();
544     
545     cout << "\n\n后序遍历树元素: \n";
546     test.PostprintTree();
547     
548     cout << "\n\n层次遍历树元素: \n";
549     test.LevelprintTree();
550     
551     cout << "\n\n先序遍历树元素(非递归): \n";
552     test.PreprintTree_N();
553     
554     cout << "\n\n中序遍历树元素(非递归): \n";
555     test.InprintTree_N();
556     
557     cout << "\n\n后序遍历树元素(非递归): \n";
558     test.PostprintTree_N();
559     
560     cout << "\n\n二叉树的树形显示算法: \n";
561     test.DisplayTreeShape(43);
562     
563     cout << endl;
564     return 0;
565 }

 

posted @ 2016-10-29 21:31 douzujun 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值