软考
APP下载

中序遍历是怎么遍历的

中序遍历是二叉树的一种遍历方式,从左根右的顺序遍历整棵树。对于每个节点,中序遍历会先遍历它的左子节点,再遍历自身,最后遍历右子节点。这种遍历方式广泛应用于对树的搜索和排序算法中。那么,我们就来看一看中序遍历是怎么遍历的。

首先,我们需要理解中序遍历的原理。对于一个二叉树来说,其中每个节点都有左右两个子节点。如下图所示:

```

1

/ \

2 3

/ \ / \

4 5 6 7

```

对于该二叉树,中序遍历的顺序是 4, 2, 5, 1, 6, 3, 7。我们可以这样来理解中序遍历:

- 遍历左子树,即先遍历节点 4。

- 遍历根节点 2。

- 继续遍历左子树,遍历节点 5。

- 遍历根节点 1。

- 遍历右子树,遍历节点 6。

- 遍历根节点 3。

- 继续遍历右子树,遍历节点 7。

从这个例子中,我们可以看出中序遍历的原理:遍历二叉树时,先遍历左子树,再遍历根节点,最后遍历右子树。这个顺序保证了遍历结果的有序性。

接下来,我们来看一下中序遍历的实现。

递归实现

最常见的中序遍历实现方式是递归实现。递归实现的代码简短易懂,如下:

```

void inorder(Node* root) {

if (root == nullptr) {

return;

}

inorder(root->left);

cout << root->val << endl;

inorder(root->right);

}

```

在这个代码中,函数 `inorder` 接收一个节点 `root`,表示以当前节点为根的子树。如果当前节点为 `nullptr`,说明子树为空,直接返回。否则,先递归遍历左子树(`root->left`),再打印根节点(`root->val`),最后递归遍历右子树(`root->right`)。

非递归实现

递归实现中序遍历的缺点是可能会造成函数调用栈溢出。因此,我们还需要另一种实现方式,即非递归实现。非递归实现不使用函数调用栈,而是使用栈这种数据结构来存储节点。

如下是中序遍历的非递归实现:

```

void inorder(Node* root) {

stack st;

Node* curr = root;

while (curr != nullptr || !st.empty()) {

while (curr != nullptr) {

st.push(curr);

curr = curr->left;

}

curr = st.top();

st.pop();

cout << curr->val << endl;

curr = curr->right;

}

}

```

这个代码使用了一个栈 `st`,来存储节点。开始时,将当前节点设置为根节点 `root`,然后进入循环。在循环中,首先遍历左子树,将所有左子节点入栈。当左子树遍历完后,弹出栈顶元素,并输出其值。如果当前节点有右子节点,将其设置为当前节点,继续遍历右子树。

在非递归实现中,我们使用了一个 while 循环对栈进行操作,从而遍历整个树,我们不再需要使用多个函数调用栈。

另外,中序遍历还有后继节点(inorder successor)的概念,即中序遍历中一个节点之后第一个被遍历的节点。后继节点通常用于删除节点和查找二叉树中一个节点的下一个节点。找到后继节点的方法是从当前节点开始向上查找,直到找到一个节点为其父节点的左孩子,这个节点就是后继节点。

备考资料 免费领取:软件设计师报考指南+考情分析+思维导图等 立即下载
真题演练 精准解析历年真题,助你高效备考! 立即做题
相关阅读
软件设计师题库