二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)

  二叉树的创建及遍历是很多二叉树问题的基础,递归遍历逻辑清晰,代码简约漂亮,然则效率低下(所有递归方案的通病,非不得已不用递归);

  非递归遍历高效,却不是能信手写出来的,特别是后续非递归遍历,相信很多资深码工也有这样的经历:

  5年前学习了二叉树的非递归遍历,一个月前复习了并达到能熟练写出的程度,在不参考任何资料的情况下,今天却怎样也写不出来。

  如果你也有过这种经历,恭喜你,这说明你是一个正常人……

  另一方面市面上有些国人写的教材,各种语法、逻辑错误层出不起,不知祸害了多少未来的码工,深感痛心。

  印象比较深刻的有清华大学出版社出版的《数据结果(C++版)》  王红梅、胡明、王涛编著

  如书中第163页后序非递归遍历方法,短短不到30行代码各种语法、逻辑错误如下:  

 1 template <typename T>
 2 void BiTree::PostOrder(BiNode<T> * root)//错误一:正确的写法为void BiTree<T>::PostOrder(BiNode<T> * root)
 3 {
 4     top = -1;
 5     //错误二:应该在这里定义下文用到的栈s(书中说这是具体的代码,不是伪代码)。
 6     wihle(root != NULL || top != -1)
 7     {
 8         while(root != NULL)
 9         {
10             top++;
11             s[top].ptr = root;
12             s[top].flag = 1;
13             root = root -> lchild;
14         }
15         while(top != -1 && s[top].flag ==2)
16         {
17             root = s[top--].ptr;
18             cout << root->data;
19         }
20         if(top != -1)
21         {
22             s[top].flag = 2;
23             root = s[top].ptr->rchild;
24         }
25         //错误三:致命逻辑错误,栈空时,应该退出外层循环,否则将进入死循环,应该加上如下一行代码。
26         //else break;
27     }
28 }

  

  下面咱们来实现一个二叉树的Class,在Class中实现以下方法:

  1.创建一颗二叉树;

2.销毁一颗二叉树;

  3.递归前序遍历方法;

  4.非递归前序遍历方法;

  5.递归中序遍历方法;

  6.非递归中序遍历方法;

  7.递归后序遍历方法;

  8.非递归后序遍历方法;

  9.层序遍历方法(这个应该就没有递归的方法)。

  要点:非递归遍历用栈辅助(深度优先),层序遍历用队列辅助(广度优先)。  

  二叉树节点定义:   

1 template <typename T>
2 struct BiNode
3 {
4     T data;
5     BiNode<T> *pLeft;
6     BiNode<T> *pRight;
7 };

  

  二叉树Class定义: 

  要点:1.数据成员申明为私有(原因见Effective C++ 条款21:将成员变量申明为private);

     2. 公有成员方法如PreOrder1()为对外接口,调用私用方法PreOrderRecursive(BiNode<T> * root)实现具体其功能。

 1 template <typename T>
 2 class BiTree
 3 {
 4     public:
 5         BiTree();
 6         ~BiTree();
 7         void PreOrder1();//递归
 8         void PreOrder2();//非递归
 9         void InOrder1();//递归
10         void InOrder2();//非递归
11         void PostOrder1();//递归
12         void PostOrder2();//非递归
13         void LevelOrder();
14     private:
15         BiNode<T> * root;
16         void CreateBiTree(BiNode<T> * &root);
17         void ReleaseBiTree(BiNode<T> * root);
18
19         void PreOrderRecursive(BiNode<T> * root);
20         void PreOrderNonRecursive(BiNode<T> * root);
21
22         void InOrderRecursive(BiNode<T> * root);
23         void InOrderNonRecursive(BiNode<T> * root);
24
25         void PostOrderRecursive(BiNode<T> * root);
26         void PostOrderNonRecursive(BiNode<T> * root);
27
28         void LevelOrder(BiNode<T> * root);
29 };

  

  创建二叉树:

 1 template <typename T>
 2 void BiTree<T>::CreateBiTree( BiNode<T> * &root)// 根据前序遍历次序创建二叉树
 3 {
 4     T data;
 5     cin>>data;
 6     if(data == INVALID)
 7     {
 8         root = NULL;
 9     }
10     else
11     {
12         root = new BiNode<T>;
13         root->data = data;
14         CreateBiTree(root->pLeft);
15         CreateBiTree(root->pRight);
16     }
17 }
18
19
20 template <typename T>
21 BiTree<T>::BiTree():root(NULL)
22 {
23     CreateBiTree(root);
24 }

  销毁二叉树:  

 1 template <typename T>
 2 void BiTree<T>::ReleaseBiTree(BiNode<T> * root)
 3 {
 4     if(root != NULL)
 5     {
 6         ReleaseBiTree(root->pLeft);
 7         ReleaseBiTree(root->pRight);
 8         delete root;
 9     }
10 }
11
12
13 template <typename T>
14 BiTree<T>::~BiTree()
15 {
16     ReleaseBiTree(root);
17 }

  前序递归遍历:  

 1 template <typename T>
 2 void BiTree<T>::PreOrderRecursive(BiNode<T> * root)
 3 {
 4     if(root != NULL)
 5     {
 6         cout<<root->data<<" ";
 7         PreOrderRecursive(root->pLeft);
 8         PreOrderRecursive(root->pRight);
 9     }
10 }
11
12
13
14 template <typename T>
15 void BiTree<T>::PreOrder1()
16 {
17     PreOrderRecursive(root);
18     cout<<endl;
19 }

  

  中序递归遍历:

 1 template <typename T>
 2 void BiTree<T>::InOrderRecursive(BiNode<T> * root)
 3 {
 4     if(root != NULL)
 5     {
 6         InOrderRecursive(root->pLeft);
 7         cout<<root->data<<" ";
 8         InOrderRecursive(root->pRight);
 9     }
10 }
11
12
13 template <typename T>
14 void BiTree<T>::InOrder1()
15 {
16     InOrderRecursive(root);
17     cout<<endl;
18 }

  

  后序递归遍历:  

 1 template <typename T>
 2 void BiTree<T>::PostOrderRecursive(BiNode<T> * root)
 3 {
 4     if(root != NULL)
 5     {
 6                 PostOrderRecursive(root->pLeft);
 7                 PostOrderRecursive(root->pRight);
 8                 cout<<root->data<<" ";
 9     }
10 }
11
12
13 template <typename T>
14 void BiTree<T>::PostOrder1()
15 {
16     PostOrderRecursive(root);
17     cout<<endl;
18 }

  

  层序遍历:  

 1 template <typename T>
 2 void BiTree<T>::LevelOrder(BiNode<T> * root)
 3 {
 4     BiNode<T> * p;
 5     queue<BiNode<T> *> q;
 6     if(root == NULL)
 7         return;
 8     q.push(root);
 9     while(!q.empty())
10     {
11         p = q.front();
12         cout << p->data<<" ";
13         q.pop();
14         if(p->pLeft != NULL) q.push(p->pLeft);
15         if(p->pRight != NULL) q.push(p->pRight);
16     }
17 }
18
19 template <typename T>
20 void BiTree<T>::LevelOrder()
21 {
22     LevelOrder(root);
23     cout<<endl;
24 }

  前序非递归遍历:

 1 template <typename T>
 2 void BiTree<T>:: PreOrderNonRecursive(BiNode<T> * root)
 3 {
 4     stack<BiNode<T> *> s;
 5     while(root != NULL || !s.empty())
 6     {
 7         while(root != NULL)
 8         {
 9             cout<<root->data<<" ";
10             s.push(root);
11             root = root->pLeft;
12         }
13         if(!s.empty())
14         {
15             root = s.top();
16             s.pop();
17             root = root->pRight;
18         }
19     }
20
21 }
22
23
24
25
26 template <typename T>
27 void BiTree<T>::PreOrder2()
28 {
29     PreOrderNonRecursive(root);
30     cout<<endl;
31 }

  中序非递归遍历:  

 1 template <typename T>
 2 void BiTree<T>::InOrderNonRecursive(BiNode<T> * root)
 3 {
 4     stack<BiNode<T> *> s;
 5     while(root != NULL || !s.empty())
 6     {
 7         while(root != NULL)
 8         {
 9             s.push(root);
10             root = root->pLeft;
11         }
12         if(!s.empty())
13         {
14             root = s.top();
15             s.pop();
16             cout<<root->data<<" ";
17             root = root->pRight;
18         }
19     }
20
21 }
22
23
24
25 template <typename T>
26 void BiTree<T>::InOrder2()
27 {
28     InOrderNonRecursive(root);
29     cout<<endl;
30 }

  后序非递归遍历:  

 1 template <typename T>
 2 void BiTree<T>::PostOrderNonRecursive(BiNode<T> * root)
 3 {
 4
 5     stack<BiNode<T> *> s1;
 6     stack<int> s2;//s2辅助记录s1相应位置的元素的状态:s1、s2保持同步。
 7
 8     while(root != NULL || !s1.empty())
 9     {
10         while(root != NULL)
11         {
12             s1.push(root);
13             s2.push(1);
14             root = root->pLeft;
15         }
16         if(!s1.empty())
17         {
18             if(s2.top()==1)
19             {
20                 s2.pop();
21                 s2.push(2);
22                 root = s1.top()->pRight;
23             }
24             else
25             {
26                 root = s1.top();
27                 s1.pop();
28                 s2.pop();
29                 cout<<root->data<<" ";
30                 root = NULL;
31             }
32         }
33
34     }
35
36 }
37
38 template <typename T>
39 void BiTree<T>::PostOrder1()
40 {
41     PostOrderRecursive(root);
42     cout<<endl;
43 }
44
45 template <typename T>
46 void BiTree<T>::PostOrder2()
47 {
48     PostOrderNonRecursive(root);
49     cout<<endl;
50 }

  

  假定我们创建的二叉树形状如下:

 1 /*
 2 假定所创建的二叉树如下图所示
 3                                              A
 4                                            /    5                                           B     C
 6                                          / \    /
 7                                         D   E  F
 8                                               9                                               G
10
11
12 创建二叉树的文件:《BiTree.txt》内容如下:
13 A B D # # E # G # # C  F # # #
14
15 */
16 const char *preorder  = "A B D E G C G";
17 const char *inorder   = "D B E G A F C";
18 const char *postorder = "D G E B F C A";
19 const char *levelorder= "A B C D E F G";

  

  main函数:

 1 int main()
 2 {
 3     ifstream fin("BiTree.txt");// 输入文件
 4     ofstream fout("out.txt");  //输出文件
 5
 6     streambuf *cinbackup;
 7     streambuf *coutbackup;
 8
 9     cinbackup= cin.rdbuf(fin.rdbuf());  //用 rdbuf() 重新定向
10     coutbackup= cout.rdbuf(fout.rdbuf());  //用 rdbuf() 重新定向
11
12     BiTree<char> *pbitree = new BiTree<char>;//创建一颗二叉树
13
14     cout << "*preorder =   " << preorder << endl;
15     cout << " PreOrder1(): ";
16     pbitree->PreOrder1();
17     cout << " PreOrder2(): ";
18     pbitree->PreOrder2();
19     cout<<endl;
20
21     cout << "*inorder =   " << inorder << endl;
22     cout << " inorder1(): ";
23     pbitree->InOrder1();
24     cout << " InOrder2(): ";
25     pbitree->InOrder2();
26     cout<<endl;
27
28     cout << "*postorder =   " << postorder << endl;
29     cout << " PostOrder1(): ";
30     pbitree->PostOrder1();
31     cout << " PostOrder2(): ";
32     pbitree->PostOrder2();
33     cout<<endl;
34
35     cout << "*levelorder =  " << levelorder << endl;
36     cout << " LevelOrder(): ";
37     pbitree->LevelOrder();
38
39     delete pbitree;
40     cin.rdbuf(cinbackup);  // 取消,恢复键盘输入
41     cout.rdbuf(coutbackup);  //取消,恢复屏幕输出
42     return 0;
43 }

  

  VC2005上的运行结果如下图:

  

  完整的代码:  

  

  1 #include <iostream>
  2 #include <fstream>
  3 #include <stack>
  4 #include <queue>
  5
  6 using namespace std;
  7
  8
  9 /*
 10 假定所创建的二叉树如下图所示
 11                                              A
 12                                            /    13                                           B     C
 14                                          / \    /
 15                                         D   E  F
 16                                               17                                               G
 18
 19
 20 创建二叉树的文件:《BiTree.txt》内容如下:
 21 A B D # # E # G # # C  F # # #
 22
 23 */
 24 const char *preorder  = "A B D E G C G";
 25 const char *inorder   = "D B E G A F C";
 26 const char *postorder = "D G E B F C A";
 27 const char *levelorder= "A B C D E F G";
 28
 29 const char INVALID = ‘#‘;//INVALID在CreateBiTree()函数中表示空节点,类型适配 template <typename T>
 30
 31 template <typename T>
 32 struct BiNode
 33 {
 34     T data;
 35     BiNode<T> *pLeft;
 36     BiNode<T> *pRight;
 37 };
 38
 39 template <typename T>
 40 class BiTree
 41 {
 42     public:
 43         BiTree();
 44         ~BiTree();
 45         void PreOrder1();//递归
 46         void PreOrder2();//非递归
 47         void InOrder1();//递归
 48         void InOrder2();//非递归
 49         void PostOrder1();//递归
 50         void PostOrder2();//非递归
 51         void LevelOrder();
 52     private:
 53         BiNode<T> * root;
 54         void CreateBiTree(BiNode<T> * &root);
 55         void ReleaseBiTree(BiNode<T> * root);
 56
 57         void PreOrderRecursive(BiNode<T> * root);
 58         void PreOrderNonRecursive(BiNode<T> * root);
 59
 60         void InOrderRecursive(BiNode<T> * root);
 61         void InOrderNonRecursive(BiNode<T> * root);
 62
 63         void PostOrderRecursive(BiNode<T> * root);
 64         void PostOrderNonRecursive(BiNode<T> * root);
 65
 66         void LevelOrder(BiNode<T> * root);
 67 };
 68
 69
 70 template <typename T>
 71 void BiTree<T>::CreateBiTree( BiNode<T> * &root)// 根据前序遍历次序创建二叉树
 72 {
 73     T data;
 74     cin>>data;
 75     if(data == INVALID)
 76     {
 77         root = NULL;
 78     }
 79     else
 80     {
 81         root = new BiNode<T>;
 82         root->data = data;
 83         CreateBiTree(root->pLeft);
 84         CreateBiTree(root->pRight);
 85     }
 86 }
 87
 88
 89 template <typename T>
 90 void BiTree<T>::ReleaseBiTree(BiNode<T> * root)
 91 {
 92     if(root != NULL)
 93     {
 94         ReleaseBiTree(root->pLeft);
 95         ReleaseBiTree(root->pRight);
 96         delete root;
 97     }
 98 }
 99 template <typename T>
100 BiTree<T>::BiTree():root(NULL)
101 {
102     CreateBiTree(root);
103 }
104
105
106 template <typename T>
107 BiTree<T>::~BiTree()
108 {
109     ReleaseBiTree(root);
110 }
111
112
113 template <typename T>
114 void BiTree<T>::PreOrderRecursive(BiNode<T> * root)
115 {
116     if(root != NULL)
117     {
118         cout<<root->data<<" ";
119         PreOrderRecursive(root->pLeft);
120         PreOrderRecursive(root->pRight);
121     }
122 }
123
124 template <typename T>
125 void BiTree<T>:: PreOrderNonRecursive(BiNode<T> * root)
126 {
127     stack<BiNode<T> *> s;
128     while(root != NULL || !s.empty())
129     {
130         while(root != NULL)
131         {
132             cout<<root->data<<" ";
133             s.push(root);
134             root = root->pLeft;
135         }
136         if(!s.empty())
137         {
138             root = s.top();
139             s.pop();
140             root = root->pRight;
141         }
142     }
143
144 }
145
146
147 template <typename T>
148 void BiTree<T>::PreOrder1()
149 {
150     PreOrderRecursive(root);
151     cout<<endl;
152 }
153
154 template <typename T>
155 void BiTree<T>::PreOrder2()
156 {
157     PreOrderNonRecursive(root);
158     cout<<endl;
159 }
160
161 template <typename T>
162 void BiTree<T>::InOrderRecursive(BiNode<T> * root)
163 {
164     if(root != NULL)
165     {
166         InOrderRecursive(root->pLeft);
167         cout<<root->data<<" ";
168         InOrderRecursive(root->pRight);
169     }
170 }
171
172 template <typename T>
173 void BiTree<T>::InOrderNonRecursive(BiNode<T> * root)
174 {
175     stack<BiNode<T> *> s;
176     while(root != NULL || !s.empty())
177     {
178         while(root != NULL)
179         {
180             s.push(root);
181             root = root->pLeft;
182         }
183         if(!s.empty())
184         {
185             root = s.top();
186             s.pop();
187             cout<<root->data<<" ";
188             root = root->pRight;
189         }
190     }
191
192 }
193
194 template <typename T>
195 void BiTree<T>::InOrder1()
196 {
197     InOrderRecursive(root);
198     cout<<endl;
199 }
200
201
202 template <typename T>
203 void BiTree<T>::InOrder2()
204 {
205     InOrderNonRecursive(root);
206     cout<<endl;
207 }
208
209 template <typename T>
210 void BiTree<T>::PostOrderRecursive(BiNode<T> * root)
211 {
212     if(root != NULL)
213     {
214                 PostOrderRecursive(root->pLeft);
215                 PostOrderRecursive(root->pRight);
216                 cout<<root->data<<" ";
217     }
218 }
219
220 template <typename T>
221 void BiTree<T>::PostOrderNonRecursive(BiNode<T> * root)
222 {
223
224     stack<BiNode<T> *> s1;
225     stack<int> s2;//s2辅助记录s1相应位置的元素的状态:s1、s2保持同步。
226
227     while(root != NULL || !s1.empty())
228     {
229         while(root != NULL)
230         {
231             s1.push(root);
232             s2.push(1);
233             root = root->pLeft;
234         }
235         if(!s1.empty())
236         {
237             if(s2.top()==1)
238             {
239                 s2.pop();
240                 s2.push(2);
241                 root = s1.top()->pRight;
242             }
243             else
244             {
245                 root = s1.top();
246                 s1.pop();
247                 s2.pop();
248                 cout<<root->data<<" ";
249                 root = NULL;
250             }
251         }
252
253     }
254
255 }
256
257 template <typename T>
258 void BiTree<T>::PostOrder1()
259 {
260     PostOrderRecursive(root);
261     cout<<endl;
262 }
263
264 template <typename T>
265 void BiTree<T>::PostOrder2()
266 {
267     PostOrderNonRecursive(root);
268     cout<<endl;
269 }
270
271 template <typename T>
272 void BiTree<T>::LevelOrder(BiNode<T> * root)
273 {
274     BiNode<T> * p;
275     queue<BiNode<T> *> q;
276     if(root == NULL)
277         return;
278     q.push(root);
279     while(!q.empty())
280     {
281         p = q.front();
282         cout << p->data<<" ";
283         q.pop();
284         if(p->pLeft != NULL) q.push(p->pLeft);
285         if(p->pRight != NULL) q.push(p->pRight);
286     }
287 }
288
289 template <typename T>
290 void BiTree<T>::LevelOrder()
291 {
292     LevelOrder(root);
293     cout<<endl;
294 }
295
296 int main()
297 {
298
299
300     ifstream fin("BiTree.txt");// 输入文件
301     ofstream fout("out.txt");  //输出文件
302
303     streambuf *cinbackup;
304     streambuf *coutbackup;
305
306     cinbackup= cin.rdbuf(fin.rdbuf());  //用 rdbuf() 重新定向
307     coutbackup= cout.rdbuf(fout.rdbuf());  //用 rdbuf() 重新定向
308
309     BiTree<char> *pbitree = new BiTree<char>;//创建一颗二叉树
310
311     cout << "*preorder =   " << preorder << endl;
312     cout << " PreOrder1(): ";
313     pbitree->PreOrder1();
314     cout << " PreOrder2(): ";
315     pbitree->PreOrder2();
316     cout<<endl;
317
318     cout << "*inorder =   " << inorder << endl;
319     cout << " inorder1(): ";
320     pbitree->InOrder1();
321     cout << " InOrder2(): ";
322     pbitree->InOrder2();
323     cout<<endl;
324
325     cout << "*postorder =   " << postorder << endl;
326     cout << " PostOrder1(): ";
327     pbitree->PostOrder1();
328     cout << " PostOrder2(): ";
329     pbitree->PostOrder2();
330     cout<<endl;
331
332     cout << "*levelorder =  " << levelorder << endl;
333     cout << " LevelOrder(): ";
334     pbitree->LevelOrder();
335
336     delete pbitree;
337     cin.rdbuf(cinbackup);  // 取消,恢复键盘输入
338     cout.rdbuf(coutbackup);  //取消,恢复屏幕输出
339     return 0;
340 }

  

  

  

  

时间: 2025-01-02 18:12:40

二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)的相关文章

数据结构:二叉树(前,中,后,层次)非递归遍历。

#include <iostream> #include <stack> #include <map> #include <queue> #include <string.h> using namespace std; struct Node { char data; Node *left; Node *right; Node(char d = char()):data(d),left(NULL),right(NULL){} }; class T

c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 4,层级遍历 二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树 编译方法,用gcc编译不过去,用g++编译,命令如下: g++ -g nodestack.c nodequeue.c bintree.c

二叉树的前序/中序/后序遍历方法的递归与循环的实现

对于二叉树的三种遍历方法, 递归方法实现起来简单,明白.但是效率不好,并且不安全,可能会栈溢出.循环的实现,肯定是基于栈的数据结构来实现,要复杂一些.代码如下: 前序遍历的实现: // 前序遍历 ----基于递归 void PreorderTraversal(BinaryTreeNode* pRoot_) { // 为空时,直接返回了 if (!pRoot_) return; std::cout << pRoot_->m_nValue << " "; Pr

二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例

二叉树的基础性质及二叉树的建立参见前面两篇博文: http://blog.csdn.net/why850901938/article/details/51052936 http://blog.csdn.net/why850901938/article/details/51052156 首先为了讲解方便,我建立了如图所示的二叉树: 取名为:树A 1.何为层序遍历? 层序遍历就是按照二叉树的层次由上到下的进行遍历,每一层要求访问的顺序为从左到右: 以树A为例,层序遍历得到的结果为: 5 2 6 1

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

二叉树的先序-中序-后序遍历(一)-循环----绝对白痴好记的方法

接着上一篇 二叉树的先序-中序-后序遍历(一)-递归 的讲,这篇该循环遍历了. 之前一直没有找到好的方法来循环遍历树,以前我老认为有些递归的能做的东西很难换成循环实现. 后来看了一些别人写的代码,然后又问了朋友,才发现...哦,原来这样的啊,我可以自己弄个栈来维护一下. 想到了可以弄个栈以后,至少在我认为,把递归转成循环已经是可行的了,至于怎么实现,这几天在想(因为太笨,看人家的代码总看一半就不想看),今天找到了一个好用的方法,在这里分享一下. 算法的核心是:你看二叉树的时候心里怎么想的,程序就

关于二叉树的几种遍历方法

转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/38390513 作者:小马 一 二叉树的一些概念 二叉树就是每个结点最多有两个子树的树形存储结构.先上图,方便后面分析. 1 满二叉树和完全二叉树 上图就是典型的二叉树,其中左边的图还叫做满二叉树,右边是完全二叉树.然后我们可以得出结论,满二叉树一定是完全二叉树,但是反过来就不一定.满二叉树的定义是除了叶子结点,其它结点左右孩子都有,深度为k的满二叉树,结点数就是2的k次方减1.完

日常学习随笔-用链表的形式实现普通二叉树的新增、查找、遍历(前、中、后序)等基础功能(侧重源码+说明)

一.二叉树 1.二叉树的概念 二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree),其次序不能任意颠倒. 2.性质 (1)若二叉树的层次从0开始,则在二叉树的第i层至多有2^i个结点(i>=0): (2)高度为k的二叉树最多有2^(k+1) - 1个结点(k>=-1). (空树的高度为-1): (3)对任何一棵二叉树,如果其叶子结点(度为0)数为m, 度为2的结点数为n,

二叉树——前序遍历、中序遍历、后序遍历、层序遍历详解(递归非递归)

前言 前面介绍了二叉排序树的构造和基本方法的实现.但是排序遍历也是比较重要的一环.所以笔者将前中后序.和层序遍历梳理一遍. 了解树的遍历,需要具有的只是储备有队列,递归,和栈.这里笔者都有进行过详细介绍,可以关注笔者数据结构与算法专栏.持续分享,共同学习. 层序遍历 层序遍历.听名字也知道是按层遍历.我们知道一个节点有左右节点.而每一层一层的遍历都和左右节点有着很大的关系.也就是我们选用的数据结构不能一股脑的往一个方向钻,而左右应该均衡考虑.这样我们就选用队列来实现. 对于队列,现进先出.从根节