前面讲过了二叉树的基本构造方法,于此我们来审察二叉树的三种遍历方法
- 先序遍历
(preorder
traversal, root->left->right)
- 中序遍历
(inorder
traversal, left->root->right)
- 后序遍历
(postorder
traversal, left->right->root)
以洛谷 P1305
的衍生题目QUST Q1295
为例。
假设我们现在所得到的一棵二叉树上节点的内容为整型数据,输入为
1 2 3 4 5 6 7 8 9 10
| 9 0 1 4 1 2 3 2 -1 -1 3 -1 -1 4 5 8 5 6 7 6 -1 -1 7 -1 -1 8 -1 -1
|
容易发现这是一棵拥有九个节点的二叉树如下,其个节点上的值
即为该节点的编号
root: 0 (根节点)
/ \
1 4
/ \ / \
2 3 5 8
/ \
6 7
Construction
对于容量未知的二叉树1,我们会用一个足够大的数组或者vector
来存储其节点
C++1 2 3 4
| struct Node { int val; struct Node *parent, *lchild, *rchild; } *root, *treenodes[393939];
|
在这道题目中,我们不仅把编号存储到节点的值
当中,同时也会放在数组中对应索引的位置
C++1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| for (int k = 0; k != m; ++k) { int idx, lch, rch; scanf("%d %d %d", &idx, &lch, &rch); if (treenodes[idx] == nullptr) { treenodes[idx] = (struct Node *)malloc(sizeof(struct Node)); treenodes[idx]->val = idx; } if (lch != -1) { if (treenodes[lch] == nullptr) { treenodes[lch] = (struct Node *)malloc(sizeof(struct Node)); treenodes[lch]->val = lch; } treenodes[idx]->lchild = treenodes[lch]; treenodes[lch]->parent = treenodes[idx]; } if (rch != -1) { if (treenodes[rch] == nullptr) { treenodes[rch] = (struct Node *)malloc(sizeof(struct Node)); treenodes[rch]->val = rch; } treenodes[idx]->rchild = treenodes[rch]; treenodes[rch]->parent = treenodes[idx]; } }
root = treenodes[0]; while (root->parent != nullptr) root = root->parent;
|
此即主函数中构造这棵树的方法。
Traversal
例如先序遍历的输出过程,其处理顺序为根-左-右
,按照这样的顺序进行输出的函数如下:
C++1 2 3 4 5 6 7
| void __print_preorder(struct Node *rt) { if (rt != nullptr) { printf(" %d,", ); __print_preorder(rt->lchild); __print_preorder(rt->rchild); } }
|
因为先序遍历是先处理根节点,然后再先后处理左子树和右子树,处理左右子树的时候也是按照顺序处理根-左-右
,因此形式上是递归的。
References
1. 百度百科词条 二叉树 ↩