一、中序遍历
中序遍历过程:先访问左子节点,然后访问当前节点,最后访问右子节点。
以下试一次中序遍历过程:
二、非递归实现
非递归方式遍历依赖栈来实现,因为要先访问子节点,然后访问父节点,因此必须要有一个数据结构来保存已经父节点。
实现原理:
- 每次遍历到一个节点,不访问它,先压栈,然后对左子树循环做这个操作。
- 遍历左节点直到左节点为空时,取出栈顶元素,访问它。
- 然后对这个栈顶元素的右节点重复执行第一个步骤。
大致的逻辑和前序遍历差不多,相对于前序遍历而言,中序遍历知识把访问节点的时机延后了一些。前序遍历可以参考二叉树的先序遍历。
代码描述:
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 |
/* * 中序遍历的非递归实现 * @node 需要遍历的节点 * @v 保存遍历结果的数组 */ void in_order_traversal_by_stack(tree_node<T> *node, vector<T> &v) { stack<tree_node<T> *> st; tree_node<T> *p; p = node; while (p || !st.empty()) { // 左子树压栈 while (p) { st.push(p); p = p->lchild; } if (!st.empty()) { // 取出栈顶元素 p = st.top(); st.pop(); // 访问节点 v.push_back(p->data); // 设置指针为右子节点 p = p->rchild; } } } |
三、递归实现
递归实现很简单,不做详细描述:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* * 中序遍历的递归实现 * @node 需要遍历的节点 * @v 保存遍历结果的数组 */ void in_order_traversal(tree_node<T> *node, vector<T> &v) { if (node == nullptr) return; if (node->lchild) in_order_traversal(node->lchild, v); v.push_back(node->data); if (node->rchild) in_order_traversal(node->rchild, v); } |
评论