我的算法在函数树中插入节点有哪些缺陷?

时间:2015-06-17 05:20:39

标签: c algorithm parsing data-structures tree

我正在研究一种用数学函数构建树的算法。例如:

x^2+5*3

构建到

     /   +    \
    /          \
  / ^ \      / * \
  x   2     5     3

树的节点是对象

typedef struct node
{
    char * fx; // function
    struct node * gx; // left-hand side
    char * op; // operator
    struct node * hx; // right-hand side
} node;

以便上面的树实际上就像

                            (root node)
                      { 0, / , '+',  \   }
                          /           \
                         /             \
                        /               \
                       /                 \
                      /                   \
   { 0, / , '^', \ }                        { 0, / , '*', \ }
       /          \                             /          \
      /            \                           /            \
     /              \                         /              \
    /                \                       /                \
{"x", 0, 0, 0}     {"2", 0, 0, 0}         {"5", 0, 0, 0}    {"3", 0, 0, 0} 

我遇到问题的功能是在树中插入新节点的功能。例如,如果到目前为止构建的树是

  / ^ \
 /     \
x       2

我刚刚找到了运营商+和跟随它的号码5,我需要将树重建为

       /   +   \
      /         \
   / ^ \         5
  /     \
 x       2   

我尝试使用的功能看起来像

void insertInTree ( node * * curRootPtr, char * newOp, node * newNode )
{
    //    crpp: Pointer to a pointer to the node element that is the current root
    //   newOp: New operator found
    // newNode: New node corresponding to the expression following the operator

    node * rightTraveler = *curRootPtr;
    while (!0)
    {
        if (rightTraveler->op)
        {
            long thisOpIdx = strchr(opstack, *rightTraveler->op) - opstack;
            long newOpIdx = strchr(opstack, *newOp) - opstack;
            if (thisOpIdx > newOpIdx) break; // if new operator has a lower precendence than the
                                             // operator on the current node,
            rightTraveler = rightTraveler->hx;
        }
        else // reached a node that has no children
        {
            break;
        }
    }
    node * temp = rightTraveler;
    rightTraveler = malloc(sizeof(node));
    rightTraveler->gx = temp; rightTraveler->op = newOp; rightTraveler->hx = newNode;
}

其中opstack

定义
char opstack [] = {'+','-','*','^'}; // operators, with precedence sorted from lowest to highest

出于某种原因,这个功能并不起作用。它根本不是重建树。我知道哪里出错了?

1 个答案:

答案 0 :(得分:1)

你在做什么在逻辑上是不正确的。请考虑以下代码段:

node * temp = rightTraveler;//currently rightTraveler is the rightmost leaf node, say R, accessible from some node, say X(may be null)
rightTraveler = malloc(sizeof(node)); //rightTraveler is newly assigned 
rightTraveler->gx = temp; //temp is R, now accessible from new rightTraveller and from X
rightTraveler->op = newOp; //assignes values to new node
rightTraveler->hx = newNode;

所以你要做的是在X和R之间插入一个节点,同时仍然保持X和R之间的连接,因此,在你的printTree函数中,它遍历X和R之间的链接并打印相同的。这就是为什么你会得到树没有被重建的错觉。

解决方案是打破X和R之间的连接,并将链接X与newNode连接。在while循环中,在叶子节点之前停止,然后将该节点的 - > gx变量更改为newNode