📅  最后修改于: 2023-12-03 15:28:41.645000             🧑  作者: Mango
本题是 Gate 2003 年的计算机科学试题,要求编写一个程序实现将一棵二叉树按照中序遍历的顺序输出。
给定一棵二叉树,编写一个程序按照中序遍历的顺序输出该二叉树中的所有节点。二叉树的节点包含一个整数值、一个指向左子树的指针、一个指向右子树的指针、一个指向父节点的指针,并且节点之间是通过指针进行连接的。具体的类定义如下:
class Node {
public:
int val;
Node* left;
Node* right;
Node* parent;
};
函数原型为:
void inorder(Node* root);
其中,root 表示二叉树的根节点,函数无返回值,需原地修改二叉树节点的指向,使之满足中序遍历的顺序。
本题要求将一棵二叉树按照中序遍历的顺序输出,因此我们可以运用中序遍历的经典算法:
根据上述过程,我们可以先将二叉树转化为链表,然后依次输出链表中的节点即可。
具体来说,我们需要将叶子节点的指针指向它的前一节点,以便于后续遍历。对于当前节点 x,我们先递归遍历它的左子树,然后将 x 的左子树置为空,并将 x 的右子树指针转向其父节点 y,如果前驱节点 z 不为空,则将 z 的右子树指针转向 x。最后再递归遍历 x 的右子树即可。
具体实现的代码如下:
#include<bits/stdc++.h>
using namespace std;
class Node {
public:
int val;
Node* left;
Node* right;
Node* parent;
};
void inorder(Node* root) {
Node *cur = root, *pre = nullptr;
while (cur) {
if (cur->left == nullptr) {
cout << cur->val << " ";
pre = cur;
cur = cur->right;
} else {
auto last = cur->left;
while (last->right != nullptr && last->right != cur) {
last = last->right;
}
if (last->right == nullptr) { // 第一次遍历该节点
last->right = cur;
cur = cur->left;
} else { // 第二次遍历该节点
last->right = nullptr;
cout << cur->val << " ";
pre = cur;
cur = cur->right;
}
}
}
}
int main() {
Node* root = new Node{1, nullptr, nullptr, nullptr};
root->left = new Node{2, nullptr, nullptr, root};
root->right = new Node{3, nullptr, nullptr, root};
root->left->left = new Node{4, nullptr, nullptr, root->left};
root->left->right = new Node{5, nullptr, nullptr, root->left};
inorder(root);
}
上述代码中,我们实现了 inorder 函数,并在 main 函数中以样例进行测试。由于需要遍历的是节点的数值,因此我们直接输出节点的 val 值即可。
最后,执行上述代码,输出的结果为:4 2 5 1 3
,符合中序遍历的结论。