跳到主要内容

七、二叉树的遍历(递归实现)

二叉树的遍历是指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。

动态演示:四种遍历方式对比

点击上方按钮切换不同的遍历算法。 层序遍历还会展示辅助队列的变化过程,这是理解 BFS 的关键。

Step 1/23根节点 1 入队
1void levelOrder(TreeNode *root) {
2 queue<TreeNode*> q;
3 q.push(root);
4 while (!q.empty()) {
5 TreeNode* node = q.front();
6 q.pop();
7 cout << node->val;
8 if (node->left) q.push(node->left);
9 if (node->right) q.push(node->right);
10 }
11}
1234567
Queue:
1
Print:

1. 先中后序遍历规则

  • 先序遍历(NLR):根结点 → 左子树 → 右子树;
  • 中序遍历(LNR):左子树 → 根结点 → 右子树;
  • 后序遍历(LRN):左子树 → 右子树 → 根结点。

2. 先中后序代码实现

// 访问结点(示例:打印值)
void visit(BiTree T) {
printf("%d ", T->data.value);
}

// 先序遍历
void PreOrder(BiTree T) {
if (T != NULL) {
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}

// 中序遍历
void InOrder(BiTree T) {
if (T != NULL) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}

// 后序遍历
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}

3. 应用:求树的深度

int treeDepth(BiTree T) {
if (T == NULL) return 0; // 空树深度为0
int l = treeDepth(T->lchild); // 左子树深度
int r = treeDepth(T->rchild); // 右子树深度
return l > r ? l + 1 : r + 1; // 树的深度=Max(左右子树深度)+1
}

4.二叉树的层序遍历

算法思想

  • 初始化一个辅助队列
  • 根结点入队
  • 若队列非空,则队头结点出队,访问该结点,并将其左,右孩子插入队尾(如果有的话)
  • 重复上一步直至队列为空

5.层序遍历代码实现

C++
Output:
Click "Run" to see output...

6.由遍历序列构造二叉树

Img

  • 前序遍历的第一个字符就是根结点,所以A为根结点;
  • 再看中序遍历,顺序为左根右,所以A左边的BDC即为左子树,E为右子树
  • 再看BDC子树,D左边的为左孩子,右边的为右孩子,得到下图:

Img

  • 首先观察可以得到根结点为D;D左侧的EAF为左子树,右侧的BCHGI为右子树;
  • 再看前序遍历中B在前面,所以B为右子树根结点,HC为左子树,GI为右子树;得到下图:
  • 然后根据前序遍历中的根左右,中序遍历中的左根右的顺序,判断出CG为根,最终为:

Img Img

- 结论:前序、后序、层序序列的两两组合无法唯一确定一棵二叉树;一定要有中序序列!

💬 留下你的问题或见解