📜  门| GATE-CS-2003 |第 52 题(1)

📅  最后修改于: 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 表示二叉树的根节点,函数无返回值,需原地修改二叉树节点的指向,使之满足中序遍历的顺序。

解题思路

本题要求将一棵二叉树按照中序遍历的顺序输出,因此我们可以运用中序遍历的经典算法:

  1. 对左子树进行中序遍历
  2. 访问当前节点
  3. 对右子树进行中序遍历

根据上述过程,我们可以先将二叉树转化为链表,然后依次输出链表中的节点即可。

具体来说,我们需要将叶子节点的指针指向它的前一节点,以便于后续遍历。对于当前节点 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,符合中序遍历的结论。