如何将三元表达式转换为二叉树结构?

时间:2015-02-12 21:10:47

标签: binary-tree ternary-operator data-conversion

我遇到了这个具有三元表达式(a?b:c)的问题,需要将三元表达式转换为二叉树结构。

     a?b:c 

       a
      / \
     b   c

  a?b?c:d:e

     a
    / \
   b   e
  / \
 c   d

我使用使用数组实现的二叉树的方法: -

家长居住在 - i 左孩子 - 2i 正确的孩子 - 2i + 1

开始解析三元表达式,第一个字符将形成根节点,因此它将位于数组中的位置1。如果下一个字符是'?'那么后面的人物将是它的孩子所以留下孩子(在这种情况下b将在2号位置)。如果下一个字符是“:”,那么我们找到了正确的孩子(在第一种情况下是c),所以我们将其添加到位置3。

在第二种情况下,我们面对“?”在b之后,无论后面是什么,它将是它的孩子,并将分别添加到2j和2j + 1,其中j是数组中b的位置。现在我们面对“:”我们检查当前孩子的父母是否有两个孩子然后我们回溯并检查上一个节点,直到找到一个错过了正确孩子的节点。

还有其他办法吗?希望我已经表达得足够清楚。

8 个答案:

答案 0 :(得分:7)

以下是我的解决方案,已经过彻底测试。

class TreeNode {
    char c;
    TreeNode left;
    TreeNode right;

    TreeNode(char c) {
        this.c = c;
        left = null;
        right = null;
    }
}

public TreeNode tenaryToTree(String s) {
    if (s.length() == 0)
        return null;

    TreeNode root = new TreeNode(s.charAt(0));
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);

    for (int i = 1; i < s.length(); i++) {
        if (s.charAt(i) == '?') {
            TreeNode node = stack.peek();
            node.left = new TreeNode(s.charAt(i + 1));
            stack.push(node.left);
        } else if (s.charAt(i) == ':') {
            stack.pop();
            TreeNode node = stack.pop();
            node.right = new TreeNode(s.charAt(i + 1));
            stack.push(node.right);
        }
    }

    return root;
}

答案 1 :(得分:2)

这个没有使用父节点。但是使用堆栈。

    public NodeC convertTtoBT (char[] values) {
    char xx = values[0];
    NodeC n = new NodeC(xx);
    Stack<NodeC> a =  new Stack<NodeC>();
    for (int i = 1; i < values.length; i += 2) {
        if (values[i] == '?') {
            n.left = new NodeC (values[i + 1]);
            a.add(n);
            n = n.left;

        }
        else if (values[i] == ':') {
            n = a.pop();
            while (n.right != null) {
                n = a.pop();
            }             
            n.right = new NodeC (values[i + 1]);
            a.add(n);
            n = n.right;
        }
    }
    return n;
}

答案 2 :(得分:1)

我用树木想出了这样的东西。未经彻底测试:

当我看到&#39;?&#39;时,它是我的左孩子,所以添加到我的左边然后向左走。

如果我看到&#39;:&#39;,那么:

  1. 转到我的父母
  2. 如果right不为null且parent不为null,请继续使用我的父
  3. 我的右孩子是空的。添加正确。走到右边。
  4. 注意:如果有正确的孩子,你将永远不会回到根目录。

        public NodeC convertTtoBT (char[] values) {
        NodeC n = new NodeC (values[0]);
    
        for (int i = 1; i < values.length; i += 2) {
            if (values[i] == '?') {
                n.left = new NodeC (values[i + 1]);
                n = n.left;
            }
            else if (values[i] == ':') {
                n = n.parent;
                while (n.right != null && n.parent != null ) {
                    n = n.parent;
                }                    
                n.right = new NodeC (values[i + 1]);
                n = n.right;
            }
        }
        return n;
    

答案 3 :(得分:1)

想法是从左到右开始解析字符串,当你遇到'?'时,你会在树中更深入,否则只返回创建的新节点。

这是我的递归解决方案:

  struct node{
    char val;
    node *left;
    node *right;
    node(char v):val(v),left(NULL),right(NULL){
    }
};

    node* create_tree(string input, int &current){
    if(current>=(int)input.size()){
        return NULL;
    }
    node *temp = new node(input[current]);
    current+=2;
    if(current<(int)input.size()){
        if(input[current-1]=='?'){
            temp->left=create_ternary_tree(input,current);
            temp->right=create_ternary_tree(input,current);
        }
    }
    return temp;
}

答案 4 :(得分:1)

我的解决方案:    每个treenode都没有父链接,所以我使用堆栈来保存它们。    这个解决方案的优点是我只将root插入堆栈,因此在(如果x ==&#39;:&#39; {})句子中,没有while循环,没有推送句子。

    public  static TreeNode convert(String ternary) {
    char[] chs = ternary.toCharArray();
    Stack<TreeNode> stack = new Stack<TreeNode>();
    TreeNode cur=new TreeNode(chs[0]);
    TreeNode root= cur;
    for (int i=1; i<chs.length; i+=2) {
        if (chs[i]=='?') {
            stack.push(cur);
            TreeNode node = new TreeNode(chs[i+1]);
            cur.left = node;
            cur = node;
        }
        else if (chs[i]==':') {
            cur = stack.pop();
            TreeNode node = new TreeNode(chs[i+1]);
            cur.right = node;
            cur = node;

        }
    }
    return root;
}

答案 5 :(得分:0)

<?php echo get_home_url(); ?>

答案 6 :(得分:0)

从右到左遍历表达式,将任何字母作为节点推入堆栈。如果看到“?”,则不要将下一个字母作为根,而是从堆栈中弹出两个最后的节点作为左右根的子节点,然后将根推回堆栈中。

public TreeNode ternaryToTree(char[] exp) {
    LinkedList<TreeNode> stack = new LinkedList<TreeNode>();

    for (int i = exp.length-1; i >= 0; i--) {
        if (exp[i] == ':') continue;
        if (exp[i] == '?') {
            TreeNode node = new TreeNode(exp[--i]);
            node.left = stack.pop();
            node.right = stack.pop();
            stack.push(node);
        } else {
            stack.push(new TreeNode(exp[i]));
        }
    }

    return stack.isEmpty() ? null : stack.pop();
}

答案 7 :(得分:0)

如果此a?b:c?d?e:f:g?h:i?j:k是三元表达式,则树将像这样

          a
         / \
        b   c
           /  \
          d    g
         / \  / \
        e   f h  i
                / \
               j   k

下面是Java解决方案...

private static TreeNode convertTernaryExpression(String s) 
{

    Stack<TreeNode> stack = new Stack<>();

    int length = s.length();
    int index = 0;
    TreeNode rootNode = null;
    while(index < length)
    {
        while(s.charAt(index) != ':')
        {
            if(s.charAt(index) == '?' && stack.peek().right != null)
            {
                TreeNode temp = stack.pop();
                if(rootNode == null)
                {
                    rootNode = temp;
                }
                stack.push(temp.right);
            }
            stack.push(new TreeNode(s.charAt(index++)));
        }

        TreeNode left = stack.pop();
        TreeNode questionMark = stack.pop();
        TreeNode root = stack.pop();
        index++;
        TreeNode right = new TreeNode(s.charAt(index++));

        root.left = left;
        root.right = right;

        stack.push(root);
    }

    if(rootNode == null)
    {
        return stack.pop();
    }
    else
    {
        return rootNode;
    }
}

class TreeNode
{
    TreeNode left;
    TreeNode right;
    char val;
    public TreeNode(char val) 
    {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}