C语言后缀表达式转二叉树再先序、中序、后序遍历

接着前一篇博文,再将后缀表达式转为由二叉树保存数据,并分别采用先序、中序、后序遍历该二叉树。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_EXPRESSION_LENGTH 100

enum flag_kind {
    Operand = 1, Operator
};

typedef enum flag_kind Op_Kind;

struct expression_binary_tree_node {
    Op_Kind kind;
    int value;
    struct expression_binary_tree_node *left;
    struct expression_binary_tree_node *right;
};

typedef struct expression_binary_tree_node Expression_Node;
typedef struct expression_binary_tree_node *Expression_Tree;

Expression_Tree mk_single_digit_exp_node(const char *);

Expression_Tree mk_operator_exp_node(Expression_Tree, Expression_Tree, const char *);

struct stack_node_4_expression {
    Expression_Tree tree;
    struct stack_node_4_expression *next;
};

typedef struct stack_node_4_expression Expression_Stack_Node;
typedef struct stack_node_4_expression *P_Expression_Stack_Node;
typedef struct stack_node_4_expression *Stack_4_Expression;
typedef struct stack_node_4_expression **P_Stack_4_Expression;

void push_expression_stack(P_Stack_4_Expression, Expression_Tree);

void pop_expression_stack(P_Stack_4_Expression);

struct stack_node {
    char c;
    struct stack_node *next;
};

typedef struct stack_node Stack_Node;
typedef struct stack_node *P_Stack_Node;
typedef struct stack_node *Stack;
typedef struct stack_node **P_Stack;

void push_stack(P_Stack, char);

void pop_stack(P_Stack);

P_Stack_Node stack_top(P_Stack);

char *infix_2_suffix(const char *);

Expression_Tree suffix_2_expression_tree(const char *);

void pre_order_traversal_expression(const struct expression_binary_tree_node *);

void in_order_traversal_expression(const struct expression_binary_tree_node *);

void post_order_traversal_expression(const struct expression_binary_tree_node *);

int main() {
#if 0
    Stack stack = NULL;
    P_Stack p_stack = &stack;

    push_stack(p_stack, 'a');
    push_stack(p_stack, 'b');
    push_stack(p_stack, 'c');

    P_Stack_Node tmp;
    for (tmp = stack; tmp != NULL; tmp = tmp->next) {
        printf("%c\n", tmp->c);
    }
#endif

    char *input = malloc(sizeof(char) * MAX_EXPRESSION_LENGTH);
    char *i;
    for (i = input; i < input + MAX_EXPRESSION_LENGTH; ++i) {
        *i = '\0';
    }
    char *res = NULL;
    Expression_Tree suf_tree = NULL;
    while (scanf("%s", input) == 1) {
#if 0
        printf("%s\n", input);
#endif
        res = infix_2_suffix(input);
        printf("%s\n", res);
        suf_tree = suffix_2_expression_tree(res);
        pre_order_traversal_expression(suf_tree);
        printf("\n");
        in_order_traversal_expression(suf_tree);
        printf("\n");
        post_order_traversal_expression(suf_tree);
        printf("\n");
        free(res);
        res = NULL;
    }
    free(input);
    return 0;
}

void push_stack(P_Stack p_stack, char c) {
    P_Stack_Node p = malloc(sizeof(Stack_Node));
    p->c = c;
    p->next = NULL;
    if (*p_stack != NULL) p->next = *p_stack;
    *p_stack = p;
}

void pop_stack(P_Stack p_stack) {
    if (*p_stack == NULL) return;
    P_Stack_Node p = *p_stack;
    *p_stack = p->next;
    free(p);
    p = NULL;
}

P_Stack_Node stack_top(P_Stack p_stack) {
    return *p_stack;
}

char *infix_2_suffix(const char *infix) {
    size_t infix_length = strlen(infix);
    char *suffix = malloc(sizeof(char) * (infix_length + 1));
    char *i;
    for (i = suffix; i < suffix + infix_length + 1; ++i) *i = '\0';
    Stack op = NULL;
    P_Stack p_stack = &op;
    const char *j;
    i = suffix;
    for (j = infix; *j != '\0'; ++j) {
        if (isdigit(*j)) *i++ = *j;
        else {
            switch (*j) {
                case '(':
                    push_stack(p_stack, '(');
                    break;
                case ')': {
                    char c;
                    while ((c = stack_top(p_stack)->c) != '(') {
                        *i++ = c;
                        pop_stack(p_stack);
                    }
                    pop_stack(p_stack);
                    break;
                }
                case '+':
                    if (op == NULL) push_stack(p_stack, '+');
                    else {
                        while (1) {
                            if (op == NULL) break;
                            switch (stack_top(p_stack)->c) {
                                case '(':
                                    push_stack(p_stack, '+');
                                    goto label_break;
                                case '+':
                                    *i++ = '+';
                                    pop_stack(p_stack);
                                    push_stack(p_stack, '+');
                                    goto label_break;
                                case '*':
                                    *i++ = '*';
                                    pop_stack(p_stack);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                label_break:
                    break;
                case '*':
                    if (op == NULL) push_stack(p_stack, '*');
                    else {
                        while (1) {
                            if (op == NULL) break;
                            switch (stack_top(p_stack)->c) {
                                case '(':
                                case '+':
                                    push_stack(p_stack, '*');
                                    goto label_break_1;
                                case '*':
                                    *i++ = '*';
                                    pop_stack(p_stack);
                                    push_stack(p_stack, '*');
                                    goto label_break_1;
                                default:
                                    break;
                            }
                        }
                    }
                label_break_1:
                    break;
                default:
                    break;
            }
        }
    }
    while (op != NULL) {
        *i++ = stack_top(p_stack)->c;
        pop_stack(p_stack);
    }
    return suffix;
}

void push_expression_stack(P_Stack_4_Expression p_stack, Expression_Tree tree) {
    P_Expression_Stack_Node p = malloc(sizeof(Expression_Stack_Node));
    p->tree = tree;
    p->next = *p_stack != NULL ? *p_stack : NULL;
    *p_stack = p;
}

void pop_expression_stack(P_Stack_4_Expression p_stack) {
    if (*p_stack == NULL) return;
    P_Expression_Stack_Node p = *p_stack;
    *p_stack = p->next;
    free(p);
    p = NULL;
}

Expression_Tree suffix_2_expression_tree(const char *suffix_expression) {
    Stack_4_Expression exp_stack = NULL;
    P_Stack_4_Expression p_exp_stack = &exp_stack;
    const char *c = NULL;
    for (c = suffix_expression; *c != '\0'; ++c) {
        if (isdigit(*c)) {
            push_expression_stack(p_exp_stack, mk_single_digit_exp_node(c));
        } else {
            Expression_Tree t2 = exp_stack->tree;
            pop_expression_stack(p_exp_stack);
            Expression_Tree t1 = exp_stack->tree;
            pop_expression_stack(p_exp_stack);
            push_expression_stack(p_exp_stack, mk_operator_exp_node(t1, t2, c));
        }
    }
    Expression_Tree res = exp_stack->tree;
    pop_expression_stack(p_exp_stack);
    return res;
}

Expression_Tree mk_single_digit_exp_node(const char *p_digit) {
    Expression_Tree t = malloc(sizeof(Expression_Node));
    t->left = NULL;
    t->right = NULL;
    t->value = *p_digit - '0';
    t->kind = Operand;
    return t;
}

Expression_Tree mk_operator_exp_node(Expression_Tree first_operand, Expression_Tree second_operand, const char *pc) {
    Expression_Tree t = malloc(sizeof(Expression_Node));
    t->left = first_operand;
    t->right = second_operand;
    t->value = *pc;
    t->kind = Operator;
    return t;
}

void pre_order_traversal_expression(const struct expression_binary_tree_node *tree) {
    if (tree == NULL) return;
    switch (tree->kind) {
        case Operand:
            printf("%d", tree->value);
            break;
        case Operator:
            printf("%c", (char) (tree->value));
            break;
        default:
            break;
    }
    pre_order_traversal_expression(tree->left);
    pre_order_traversal_expression(tree->right);
}

void in_order_traversal_expression(const struct expression_binary_tree_node *tree) {
    if (tree == NULL) return;
    in_order_traversal_expression(tree->left);
    switch (tree->kind) {
        case Operand:
            printf("%d", tree->value);
            break;
        case Operator:
            printf("%c", (char) (tree->value));
            break;
        default:
            break;
    }
    in_order_traversal_expression(tree->right);
}

void post_order_traversal_expression(const struct expression_binary_tree_node *tree) {
    if (tree == NULL) return;
    post_order_traversal_expression(tree->left);
    post_order_traversal_expression(tree->right);
    switch (tree->kind) {
        case Operand:
            printf("%d", tree->value);
            break;
        case Operator:
            printf("%c", (char) (tree->value));
            break;
        default:
            break;
    }
}

运行结果

1+2*3
123*+
+1*23
1+2*3
123*+
1+2*3+4*5+(6+7)*8*9
123*+45*+67+8*9*+
+++1*23*45**+6789
1+2*3+4*5+6+7*8*9
123*+45*+67+8*9*+

缺陷

博文

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言代码实现后缀表达式二叉树: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct node { char data; struct node *left; struct node *right; } Node; typedef struct stack { Node *data; struct stack *next; } Stack; Node* new_node(char data) { Node *node = (Node*) malloc(sizeof(Node)); node->data = data; node->left = NULL; node->right = NULL; return node; } Stack* new_stack() { Stack *stack = (Stack*) malloc(sizeof(Stack)); stack->data = NULL; stack->next = NULL; return stack; } void push(Stack *stack, Node *node) { Stack *new_top = new_stack(); new_top->data = node; new_top->next = stack->next; stack->next = new_top; } Node* pop(Stack *stack) { if (stack->next == NULL) { return NULL; } Node *node = stack->next->data; Stack *temp = stack->next; stack->next = stack->next->next; free(temp); return node; } Node* build_expression_tree(char* postfix) { Stack *stack = new_stack(); int n = strlen(postfix); for (int i = 0; i < n; i++) { if (isdigit(postfix[i])) { Node *node = new_node(postfix[i]); push(stack, node); } else { Node *node = new_node(postfix[i]); node->right = pop(stack); node->left = pop(stack); push(stack, node); } } return pop(stack); } void inorder_traversal(Node *node) { if (node == NULL) { return; } if (node->left != NULL || node->right != NULL) { printf("("); } inorder_traversal(node->left); printf("%c", node->data); inorder_traversal(node->right); if (node->left != NULL || node->right != NULL) { printf(")"); } } int main() { char postfix[100]; printf("Enter postfix expression: "); scanf("%s", postfix); Node *root = build_expression_tree(postfix); printf("Inorder traversal: "); inorder_traversal(root); printf("\n"); return 0; } ``` 该程序首先定义了两个结构体,分别表示节点和栈。节点结构体包含数据和左右子树指针,栈结构体包含数据和下一个节点指针。接着定义了一些函数,分别用于创建新节点、创建新栈、入栈、出栈和构建表达式二叉树。其中,构建表达式二叉树的算法如下: 1. 从左到右扫描后缀表达式。 2. 如果遇到数字,就创建一个新节点,并将其压入栈中。 3. 如果遇到运算符,就创建一个新节点,从栈中弹出两个节点作为其左右子树,然后将新节点压入栈中。 4. 扫描结束后,栈中剩下的节点就是表达式二叉树的根节点。 最后,程序通过中序遍历输出表达式二叉树

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值