二叉树的先序遍历非递归实现

二叉树的先序遍历非递归实现

【问题描述】已知二叉树的后序遍历序列和中序遍历序列(二叉树中元素类型为字符类型),输出该二叉树的先序遍历序列(采用非递归方式实现)。

【输入形式】二叉树的后序序列 二叉树的中序序列

【输出形式】二叉树的先序遍历序列

【样例输入】DIGEBHFCA DBGIEAFHC

【样例输出】

ABDEGICFH  

【样例说明】

【评分标准】

  1. 定义了二叉树结构体Node,包含数据域data、左子节点指针left和右子节点指针right

  2. 实现了buildTree函数,该函数根据后序序列和中序序列构建二叉树。函数的参数包括后序序列、中序序列以及序列的起始和结束位置。

    a. 首先判断序列是否为空或长度不匹配,若是,则返回nullptr表示空树。

    b. 创建根节点,并将根节点的数据域设置为后序序列的最后一个元素。

    c. 在中序序列中查找根节点的索引位置,这里通过遍历中序序列的方式查找。

    d. 根据根节点在中序序列中的位置,计算出左子树和右子树的长度。

    e. 递归调用buildTree函数构建左子树和右子树,传入对应的后序序列和中序序列的子序列。

    f. 返回根节点。

  3. 实现了preorderTraversal函数,该函数用于非递归方式先序遍历二叉树。

    a. 如果根节点为空,直接返回空字符串。

    b. 创建一个栈nodeStack用于存储待访问的节点。

    c. 初始化当前节点为根节点。

    d. 循环遍历,直到当前节点为空且栈为空:

    • 如果当前节点不为空,表示还有左子树未访问,将当前节点的值加入先序遍历序列,并将当前节点入栈,然后将当前节点更新为其左子节点。

    • 如果当前节点为空,表示左子树已经访问完毕,从栈中弹出一个节点作为当前节点,并将当前节点更新为其右子节点。

    e. 返回先序遍历序列。

  4. main函数中,获取用户输入的后序序列和中序序列。

  5. 调用buildTree函数构建二叉树,传入后序序列、中序序列以及它们的起始和结束位置。

  6. 调用preorderTraversal函数对构建的二叉树进行先序遍历,得到先序遍历序列。

  7. 输出先序遍历序列。

#include 
#include 
#include 

using namespace std;

struct Node {
    char data;
    Node* left;
    Node* right;
};

// 根据后序序列和中序序列构建二叉树
Node* buildTree(const string& postorder, const string& inorder, int postStart, int postEnd, int inStart, int inEnd) {
    if (postStart > postEnd || inStart > inEnd)
        return NULL;

    // 创建根节点
    Node* root = new Node();
    root->data = postorder[postEnd];
    root->left = NULL;
    root->right = NULL;

    // 在中序序列中找到根节点的位置
    int rootIndex = -1;
    for (int i = inStart; i <= inEnd; i++) {
        if (inorder[i] == root->data) {
            rootIndex = i;
            break;
        }
    }

    // 分割左子树和右子树的长度
    int leftSize = rootIndex - inStart;
    int rightSize = inEnd - rootIndex;

    // 递归构建左子树和右子树
    root->left = buildTree(postorder, inorder, postStart, postStart + leftSize - 1, inStart, rootIndex - 1);
    root->right = buildTree(postorder, inorder, postEnd - rightSize, postEnd - 1, rootIndex + 1, inEnd);

    return root;
}

// 非递归先序遍历二叉树
string preorderTraversal(Node* root) {
    if (root == NULL)
        return "";

    stack nodeStack;
    Node* current = root;
    string preorder;

    while (current || !nodeStack.empty()) {
        if (current) {
            // 访问当前节点并将其入栈
            preorder += current->data;
            nodeStack.push(current);
            current = current->left;
        } else {
            Node* topNode = nodeStack.top();
            nodeStack.pop();
            current = topNode->right;
        }
    }

    return preorder;
}

int main() {
    string postorder;
    string inorder;
    cin >> postorder;
    cin >> inorder;

    // 构建二叉树
    Node* root = buildTree(postorder, inorder, 0, postorder.size() - 1, 0, inorder.size() - 1);

    // 先序遍历并输出结果
    cout << preorderTraversal(root) << endl;

    return 0;
}

你可能感兴趣的:(算法,数据结构)