Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 用负节点构建表达式树_C - Fatal编程技术网

C 用负节点构建表达式树

C 用负节点构建表达式树,c,C,我很难构建这样的二叉树: . 您可以看到像-这样的操作数节点只有一个子节点。 即使使用像+-a这样的简单树,代码也不起作用 我的代码是: // Represents a node of the required tree typedef struct node { char data; struct node *left, *right; } node; // Function to recursively build the expression tree char* add(

我很难构建这样的二叉树: . 您可以看到像
-
这样的操作数节点只有一个子节点。 即使使用像
+-a
这样的简单树,代码也不起作用

我的代码是:

    // Represents a node of the required tree 
typedef struct node { char data; struct node *left, *right; } node; 

// Function to recursively build the expression tree 
char* add(node** p, char* a) 
{ 

// If its the end of the expression 
if (*a == '\0') 
    return '\0'; 

while (1) { 
    char* q = "null"; 
    if (*p == NULL) { 

        // Create a node with *a as the data and 
        // both the children set to null 
        node* nn = (node*)malloc(sizeof(node));
        nn->data = *a; 
        nn->left = NULL; 
        nn->right = NULL; 
        *p = nn; 
    } 
    else { 

        // If the character is an operand 
        if (*a >= 'a' && *a <= 'z') { 
            return a; 
        } 

        // Build the left sub-tree 
        q = add(&(*p)->left, a + 1); 

        // Build the right sub-tree 
        q = add(&(*p)->right, q + 1); 

        return q; 
    } 
  } 
} 

int main() 
    { 
    node* s = NULL; 
    char a[] = "+-a"; 
    add(&s, a); 
    return 0; 
    }
//表示所需树的节点
typedef结构节点{char data;结构节点*左,*右;}节点;
//函数递归地构建表达式树
char*add(节点**p,char*a)
{ 
//如果它是表达式的结尾
如果(*a=='\0')
返回“\0”;
而第(1)款{
char*q=“null”;
如果(*p==NULL){
//创建一个以*a作为数据的节点,然后
//两个子项都设置为null
node*nn=(node*)malloc(sizeof(node));
nn->data=*a;
nn->left=NULL;
nn->right=NULL;
*p=nn;
} 
否则{
//如果字符是操作数
如果(*a>='a'&&*a左,a+1);
//构建正确的子树
q=加(&(*p)->右,q+1);
返回q;
} 
} 
} 
int main()
{ 
node*s=NULL;
字符a[]=“+-a”;
添加(&s,a);
返回0;
}

感谢您的帮助片段中有矛盾之处,而且没有意义。很难知道从哪里开始解释发生了什么

我想首先要做的一件事是,这不是一个应用递归的好地方。问题的一部分本质上是迭代的:您希望遍历字符串。将其与递归算法相结合显然会让你头疼,因为你根本做不好。一般来说,递归是一个陷阱,使事情迭代会产生更干净的代码。“需要”递归的数据结构通常也是陷阱

无论如何,我最终会给出一个有效的递归算法。现在,来剖析你做错了什么。从add返回char指针立即是一个巨大的危险信号:让指针算法在递归中工作是困难的,因为更改必须在调用堆栈中显示。从代码中消除这一点显然是一个开始

接下来是while循环。循环本质上是一个迭代的东西,但是你把它包含在一个递归算法中:希望它本质上的迭代性质开始变得清晰。使用while循环的原因也是非常愚蠢的:使用完全不必要的if-else进行拆分。正确的做法是只需在每次调用时分配一个新节点,而不必使用if,因为在已经存在的节点上,您永远不会按原样重复出现,而且您肯定不需要else,因为无论是否必须分配新节点,递归逻辑都需要发生。因此,删除while循环和if-else

接下来是q变量。我不知道你想用它做什么,但不管怎样,它都是垃圾。远离的。分配新节点时的一个次要问题是,不需要新变量来分配新节点:只需使用*p即可。这将保存一行代码

最后我们讨论递归逻辑。我已经谈到了q的问题,所以不需要详细说明。这里的逻辑根本不起作用,因为您没有以正确的方式遍历字符串。同样,在递归算法中执行此操作比以迭代方式编写要困难

下面是实际工作的代码。我非常自由地压缩源代码,这样算法在垂直方向上占用更少的空间,因为节省LoC是一件好事

int add(node** p, char* a, int i) {
    if (a[i] == '\0') return i; // If end of expression 
     *p = (node*) malloc(sizeof(node));
    (*p)->data = a[i];
    (*p)->left = (*p)->right = NULL;
    if (a[i] >= 'a' && a[i] <= 'z') return i;   // If the character is an operand 
    i = add(&(*p)->left , a, ++i);
    if (a[i] == '\0')   return i;   // If its the end of the expression 
    i = add(&(*p)->right, a, ++i);
    return i;
}
intadd(节点**p,字符*a,inti){
if(a[i]='\0')返回i;//如果表达式结束
*p=(node*)malloc(sizeof(node));
(*p)->数据=a[i];
(*p)->左=(*p)->右=空;
如果(a[i]>='a'&&a[i]左,a,++i);
if(a[i]='\0')返回i;//如果它是表达式的结尾
i=加(&(*p)->右,a,++i);
返回i;
}

i变量用于计算通过字符串的路径。您必须修改main中的初始add调用以适应。

+-a
作为一个表达式没有多大意义,我也不完全确定应该生成什么样的树。我可以看出
-a+b
是有意义的,但是对于您显示的树,是否有括号,或者这只是LTR优先级?更多的规范和预期行为的其他示例在这里会有所帮助。你对二进制和一元运算的消歧规则是什么?是否允许使用前导
+
,例如
+a
?谢谢。你可能需要一个电话。