You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表实现中缀转后缀代码问题:非括号包裹时运算符丢失求助

中缀转后缀表达式代码调试问题

我是编程初学者,已花费三小时调试基于链表实现的中缀转后缀代码。最初输入带运算符的表达式时无输出,无运算符时可正常输出。修正isOperand参数问题后,仅当整个表达式被括号包裹时代码才正常运行,否则仅输出数字,运算符丢失,恳请帮忙排查原因。

初始代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct node{
    char data;
    struct node *next;
};

struct node *top = NULL;               

void push(char x){
    struct node *temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = top;
    top = temp;
}

char pop(){
    struct node *temp = top;
    char op;

    if(top == NULL){
        printf("Stack Empty");
        exit(1);
    }
    op = top->data;
    temp = top;
    top = temp->next;
    free(temp);
    return op;
}

int precedence(char x){
    switch (x){
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        case '^':
            return 3;
    }
    return 0;
}

bool isOperand(char x){
    if(x=='^' || x=='/' || x=='+' || x=='-' || x=='*') return 1;
    else return 0;
}

int main(){
    char x[100];
    char c[100];
    printf("Enter infix expression: \n");
    scanf("%s", c);
    
    int i = 0;
    int j =0;

    while(c[i]){
        if(isOperand){
           if ((precedence(c[i])) >= (precedence(top->data)) || top == NULL || top->data == '('){
                push(c[i]);
            }
            else{
                x[j] = pop();
                j++;
                push(c[i]);
            }
        }
        else if(c[i] == '('){
            push(c[i]);
        }
        else if(c[i] == ')'){
            while(top->data != '('){
                x[j] = pop();
                j++;
            }
            pop();
        }
        else{
            x[j] = c[i];
            j++;
        }
        i++;
    }

    printf("%s", x);
}

修改后代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct node{
    char data;
    struct node *next;
};

struct node *top = NULL;

void push(char x){
    struct node *temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = top;
    top = temp;
}

char pop(){
    struct node *temp = top;
    char op;

    if(top == NULL){
        printf("Stack Empty");
        exit(1);
    }
    op = top->data;
    temp = top;
    top = temp->next;
    free(temp);
    return op;
}

int precedence(char x){
    switch (x){
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        case '^':
            return 3;
    }
    return 0;
}

bool isOperand(char x){
    if(x=='^' || x=='/' || x=='+' || x=='-' || x=='*') return 1;
    else return 0;
}

int main(){
    char x[100];
    char c[100];
    printf("Enter infix expression: \n");
    scanf("%s", c);
    
    int i = 0;
    int j = 0;

    while(c[i]){

        if(isOperand(c[i])){
           if (top == NULL || (precedence(c[i])) >= (precedence(top->data)) || top->data == '('){
                push(c[i]);
            }
            else{
                x[j] = pop();
                j++;
                push(c[i]);
            }
        }
        else if(c[i] == '('){
            push(c[i]);
        }
        else if(c[i] == ')'){
            while(top->data != '('){
                x[j] = pop();
                j++;
            }
            pop();
        }
        else{
            x[j] = c[i];
            j++;
        }
        i++;

    }

    printf("%s", x);
}

问题排查与修正方案

核心问题1:未处理栈中剩余运算符

当表达式遍历完成后,栈内可能还有未弹出的运算符(无括号包裹时,这些运算符不会被触发弹出),这就是无括号时运算符丢失的核心原因。必须在遍历结束后,循环弹出栈中所有剩余运算符,添加到结果字符串中。

核心问题2:结果字符串未加终止符

字符数组x作为字符串输出时,必须以'\0'结尾,否则会输出内存中多余的乱码内容。

次要问题:函数命名混淆

isOperand函数实际判断的是运算符(operator),不是操作数(operand),命名错误会导致逻辑混淆,建议改为isOperator。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct node{
    char data;
    struct node *next;
};

struct node *top = NULL;

void push(char x){
    struct node *temp = (struct node*)malloc(sizeof(struct node));
    temp->data = x;
    temp->next = top;
    top = temp;
}

char pop(){
    struct node *temp = top;
    char op;

    if(top == NULL){
        printf("Stack Empty");
        exit(1);
    }
    op = top->data;
    temp = top;
    top = temp->next;
    free(temp);
    return op;
}

int precedence(char x){
    switch (x){
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        case '^':
            return 3;
    }
    return 0;
}

// 修正函数命名,明确是判断运算符
bool isOperator(char x){
    if(x=='^' || x=='/' || x=='+' || x=='-' || x=='*') return 1;
    else return 0;
}

int main(){
    char x[100];
    char c[100];
    printf("Enter infix expression: \n");
    scanf("%s", c);
    
    int i = 0;
    int j = 0;

    while(c[i]){
        if(isOperator(c[i])){
            // 确保top不为空时再访问top->data,循环弹出高/平优先级运算符
            while(top != NULL && top->data != '(' && precedence(c[i]) <= precedence(top->data)){
                x[j++] = pop();
            }
            push(c[i]);
        }
        else if(c[i] == '('){
            push(c[i]);
        }
        else if(c[i] == ')'){
            while(top->data != '('){
                x[j++] = pop();
            }
            pop(); // 弹出左括号,不加入结果
        }
        else{ // 操作数直接加入结果
            x[j++] = c[i];
        }
        i++;
    }

    // 弹出栈中剩余的所有运算符
    while(top != NULL){
        x[j++] = pop();
    }

    // 添加字符串终止符
    x[j] = '\0';

    printf("Postfix expression: %s\n", x);
    return 0;
}

修正说明

  1. 添加了遍历结束后弹出栈中剩余运算符的逻辑,确保所有运算符都能加入结果。
  2. 给结果字符串x添加了'\0'终止符,避免乱码。
  3. 重命名isOperand为isOperator,明确函数功能。
  4. 优化了运算符入栈的判断逻辑,用while循环替代单次弹出,处理连续高优先级运算符的情况(比如a+b*c会先弹出*再入栈+)。

内容的提问来源于stack exchange,提问作者Saad Rizvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:15:38