根据字符串构建二进制搜索树

时间:2019-06-02 05:00:11

标签: c++ recursion binary-search-tree

我正在尝试从字符串构建二进制搜索树。字符串的格式为:((。(。$。Z))(。A.n)),其中树的5个叶节点用句点表示,而4个内部节点用括号括起来。二进制树的格式应为:

Picture of binary tree for string ((. (.$.Z))(.A.n))

我无法确定如何执行此操作;我已尝试调整此网站上提供的类似问题的解决方案:https://www.geeksforgeeks.org/construct-binary-tree-string-bracket-representation/

在我准备编写采访采访时,非常感谢您能提供的任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:0)

正如我所看到的,仅需遵循一些规则。根据要处理的字符,您可以选择以下选项:

  1. 如果它是“(”,则表示您必须根据在此操作之前执行的操作,在左侧或右侧更深地构建树
  2. 如果它是“。”,则应读取字符串中的下一个元素以确定节点值,然后,应在递归中将步骤返回为“。”。代表一片叶子
  3. 如果它是“)”,则意味着您已完成节点的子树的构建,因此必须再次返回递归中的一步

有关如何实施此操作的一些建议:

  1. 编写一个将字符串作为输入的递归函数
  2. 该函数还应该返回一个字符串,该字符串表示仍有待进一步处理的字符串
  3. 如果您的字符串在任何步骤为空,则表示要处理的字符串无效
  4. 每次完成节点的左或右子树构建时,都应检查“)”

希望这对您的面试有帮助并祝您好运!

答案 1 :(得分:0)

我想到的解决方案是基于堆栈的迭代解决方案。它要遵循一些规则:

  1. 将任何东西压入堆栈
  2. 如果遇到堆栈中的),请开始删除元素,直到遇到(,然后将其弹出。
  3. 在步骤2中弹出元素时,将它们存储在向量中,)(除外。
  4. 创建一个树节点,并将父级的子级标记为向量中的所有元素。
  5. 将父节点推回堆栈。

让我们看一下您的示例: S = "((a($Z))(An))",为清楚起见更改了' ' -> 'a'

注意:堆栈向右生长。

Stack["((a($Z"]
encounter ')'
Stack["((a"], vector<"Z$">
reverse vector -> vector<"$Z">
Parent Node -> N(id='1'), children -> <N(id='$'), N(id='Z')>
push N(1) to stack

Stack["((a1]
encounter ')'
Stack["("], vector<"1a">
reverse vector -> vector<"a1">
Parent Node -> N(id='2'), children -> <N(id='a'), N(id=1)>
push N(2) to stack

Stack["(2(An"]
encounter ')'
...

您可以继续此操作以到达顶部。完成后,即字符串用尽,您将在堆栈中只剩下一个元素,该元素将成为您的父元素或树的根。

代码:

Node* solve(string s) {
    stack<Node *> st;
    int idx = 0, rt = 1;
    while (idx < s.size()) {
        Node *n = get_node(s[idx]);
        st.push(n);
        ++idx;

        if (st.top()->v == ')') {
            st.pop();
            vector<Node *> child;
            while (st.size() && st.top()->v != '(') {
                child.push_back(st.top()); st.pop();
            }
            if (st.top()->v == '(') st.pop();

            Node *par = get_node('0' + rt++);
            reverse(child.begin(), child.end());
            for (Node *t : child) {
                t->parent = par;
                par->child.push_back(t);
            }
            st.push(par);
        }
    }
    return st.top();
}

Full Working code

此代码是常规实现,因此任何节点都可以具有尽可能多的子代,因此构造了n-arry树。 例如:

input: ((a($Zk))(An))
output:
Parent: 4: 2 3
Parent: 2: a 1
Parent: 3: A n
Parent: 1: $ Z k