二叉树的括号表示法->构建二叉树

事情的起因还是因为数据结构课的一个课后题,

题目给出了很标准的表示法的一个样例:1(2(4,5),3);一目了然,非常标准,然而这天杀的题目居然在平台测试的时候还有这种玩意儿(一个简短的例子)1(2(3),4)。我:....... 很难想象这种不标准的括号表示法到底是谁在用。

废话不多说,上硬货。网上的几种括号表示法不出下面几种 :

①A(B,C(D,E)) 、A(B(C,)D) 、A(B(,C),D) ; ②A(B(C),D) ; ③A(B(D,#), C(#,E))

针对第三种这种很规范的表示法,我们很容易就能创建出二叉树,这里不详细介绍,主要提供前两种情况下二叉树的创建

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<cstdio>
#define MY_DEBUG(n) std::cout << #n << " = " << n << std::endl
using namespace std;
struct treenode
{
    int data;
    treenode *left;
    treenode *right;
    
    treenode(int number=0)
    {
        data = number;
        left= nullptr;
        right = nullptr;
    }
};

struct node
{
    int data;
};

struct tree
{
    treenode *root;
    void Init()
    {
        root = init_tree();
    }
    treenode *init_tree();
};

void createTree(treenode*& root, string& str) {
    stack<treenode*> s3;
    treenode *p = nullptr;
    int k = 0;
    node tmp;
    root = nullptr;
    std::string::size_type i = 0;

    while (i < str.size()) {
        switch (str[i]) {
        case '(':
            if (p != nullptr) {
                s3.push(p);
            }
            k = 1;
            break;
        case ')':
            if (!s3.empty()) {
                p = s3.top(); // 更新 p 为栈顶元素的父节点
                s3.pop();
            }
            break;
        case ',':
            k = 2;
            break;
        default:
            p = new treenode; // 创建新节点
            p->left = p->right = nullptr;
            // [处理数字赋值给 p->data 的代码]
            tmp.data = str[i]-'0';
            //MY_DEBUG(str[i]);
            std::string::size_type j=i+1;
            if(str[j]>='0'&&str[j]<='9')
            {
                while(str[j]>='0'&&str[j]<='9')
                {
                    tmp.data=tmp.data*10+str[j]-'0';//将字符串转换为数字
                    j++;i++;
                }
                i=j-1;
            }
            //MY_DEBUG(tmp.data);
            p->data=tmp.data;
            if (root == nullptr) {
                root = p;
            } else if (!s3.empty()) {
                if (k == 1) s3.top()->left = p;
                else if (k == 2) s3.top()->right = p;
            }
        }
        i++;
    }
}

void left2rightOrder(treenode *p)
{
    if(p == nullptr)return ;
    if(p != nullptr) {
        // 如果节点是叶子节点,打印它的数据
        if(p->left == nullptr && p->right == nullptr) {
            cout << p->data << " ";
        }
        // 否则,递归遍历左子树和右子树
        else {
            left2rightOrder(p->left);
            left2rightOrder(p->right);
        }
    }
}

void right2leftOrder(treenode *p)
{
    if(p != nullptr) {
        // 如果节点是叶子节点,打印它的数据
        if(p->left == nullptr && p->right == nullptr) {
            cout << p->data << " ";
        }
        // 否则,递归遍历左子树和右子树
        else {
            right2leftOrder(p->right);
            right2leftOrder(p->left);
        }
    }
}

void printTree(treenode *root) {
    if (!root) return;

    queue<treenode*> q;
    q.push(root);
    while (!q.empty()) {
        int levelSize = q.size(); 
        vector<int> levelNodes;

        for (int i = 0; i < levelSize; ++i) {
            treenode* node = q.front();
            q.pop();
            levelNodes.push_back(node->data);  

            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }

        for (int i = levelNodes.size() - 1; i >= 0; --i) {
            cout << levelNodes[i] << " ";
        }
    }
}

void preorderTraversal(treenode* root)
{
    if (root == nullptr) {
        return;
    }
    cout << root->data << " "; 
    preorderTraversal(root->left); 
    preorderTraversal(root->right); 
    
}

int main()
{
    //freopen("in.txt", "r", stdin);
    string str;
    cin>>str;
    tree * tree2 = new tree;
    createTree(tree2->root,str);
    left2rightOrder(tree2->root);cout<<endl;
    right2leftOrder(tree2->root);cout<<endl;
    printTree(tree2->root);
    
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值