c++版本后序遍历功能实现

参考先序遍历,自己实现了一遍c++后序遍历的三个功能:递归打印、序列化成字符串输出、字符串反序列化(通过vector数组转化)。代码如下。

思路:反序列化要注意的点就是,和先序遍历不一样,先序遍历是第一个就是根节点,而后序遍历是后面是根节点。

所以我选择先转化成vector数组,然后通过.back和.pop_back两个函数读最后一个元素并移除,这个元素作为根节点node,然后先构造node的右子树,再构造node的左子树。

复制代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct TreeNode
{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};

//递归打印后序遍历
void lastOrderRecur(TreeNode* head)
{
    if (head == nullptr)
        return;
    lastOrderRecur(head->left);
    lastOrderRecur(head->right);
    cout << head->val << ", ";
}


//按照节点后序遍历进行序列化成一个字符串
string serialByLastOrder(TreeNode* head)
{
    //如果是空节点就序列化成#!
    if (head == nullptr)
    {
        return "#!";
    }
    string res = serialByLastOrder(head->left);
    res = res + serialByLastOrder(head->right);
    res = res + std::to_string(head->val) + "!";
    return res;
}

//按照一个字符串数组构造出一棵树并返回这棵树的根节点
//关键就在于这个引用就地改变
TreeNode* deserialByLastHelp(vector<int>& vec)
{
    int value = vec.back();
    vec.pop_back();
    if (value == -1)
        return nullptr;
    TreeNode* node = new TreeNode(value);
    node->right = deserialByLastHelp(vec);
    node->left = deserialByLastHelp(vec);
    return node;
}

//123!#!
TreeNode* deserialByLastOrder(char* str)
{
    vector<int> vec;
    //考察到字符串的反向遍历
    //首先要把str这个字符串转化成一个vector<int>数组,因为字符串不好从后面遍历
    //首先判断一下这是不是一棵空树
    if (str == nullptr)
        return nullptr;
    while(*str)
    {
        while (*str == '#')
        {
            //如果是空节点干脆就存-1进去,避免和0冲突了
            vec.push_back(-1);
            str++; str++;
        }
        int val = 0;
        while (*str != '!')
        {
            val = 10 * val + (*str - '0');
            str++;
        }
        vec.push_back(val);
        str++;//同时要跳过那个!
    }
    cout << "vec see:";
    for (auto start = vec.begin(); start != vec.end(); start++)
    {
        cout << *start << ",";
    }
    return deserialByLastHelp(vec);
}


int main()
{
    TreeNode* head = new TreeNode(5);
    head->left = new TreeNode(3);
    head->right = new TreeNode(8);
    head->left->left = new TreeNode(1);
    head->left->right = new TreeNode(2);
    head->right->left = new TreeNode(4);
    head->right->right = new TreeNode(5);
    head->right->left->left = new TreeNode(6);
    head->right->right->left = new TreeNode(9);
    head->right->right->right = new TreeNode(11);
    
    cout << "last-order:";
    lastOrderRecur(head);
    cout << "\nserial binary:";
    string res = serialByLastOrder(head);
    cout << res << endl;
    char* s_char = (char*)res.c_str();//从string转换到char*
    TreeNode* dehead = deserialByLastOrder(s_char);
    cout << "\ndeserial binary:";
    lastOrderRecur(dehead);
    
    return 0;
}
复制代码

 

posted @   花与不易  阅读(337)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示