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

三个功能:先序遍历打印、节点先序遍历序列化、字符串先序遍历反序列化

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#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 @   花与不易  阅读(154)  评论(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代理 了,记录一下
点击右上角即可分享
微信分享提示