数据结构(C语言版)严蔚敏->链栈的定义、利用链栈将中缀表达式转换成后缀表达式

listack.h

#ifndef LISTACK_H_INCLUDED
#define LISTACK_H_INCLUDED

typedef char LElemType;

typedef struct Linknode{
    LElemType data;
    struct Linknode *next;
}LNode,*LStack;

void Init_LStack(LStack &L);
// 初始化链栈
void Clear_LStack(LStack &L);
//清空链栈
bool LStackEmpty(LStack L);
//判断链栈是否为空
int LStackLength(LStack L);
//返回链栈的长度
bool GetTop(LStack L,LElemType &e);
//得到链栈的栈顶元素
void PushLStack(LStack &L,LElemType e);
 //将元素e插入到链栈的栈顶
bool PopLStack(LStack &L,LElemType &e);
 //删除链栈的栈顶元素,并且用e返回删除的元素

#endif // LISTACK_H_INCLUDED

listack.cpp

#include "listack.h"
#include <stdlib.h>

// 带头节点
void Init_LStack(LStack &L){
    L = (LNode*)malloc(sizeof(LNode));
    if(!L)
        exit(-1);
    L->next = NULL;
}

void Clear_LStack(LStack &L){
    LNode *p = L->next,*r;
    while(p!=NULL){
        r = p;
        p = p->next;
        free(r);
    }
}

bool LStackEmpty(LStack L){
    return L->next == NULL;
}

int LStackLength(LStack L){
    int i = 0;
    LNode *p = L->next;
    while(p!=NULL){
        p = p->next;
        ++i;
    }
    return i;
}

bool GetTop(LStack L,LElemType &e){
    if(L->next==NULL)
        return false;
    e = L->next->data;
    return true;
}

void PushLStack(LStack &L,LElemType e){
    LNode *p = (LNode *)malloc(sizeof(LNode));
    if(!p)
        exit(-1);
    p->data = e;
    p->next = L->next;
    L->next = p;
}

bool PopLStack(LStack &L,LElemType &e){
    if(L->next==NULL)
        return false;
    e = L->next->data;
    LNode *p = L->next;
    L->next = p->next;
    free(p);
    return true;
}

change.cpp

#include "listack.h"
#include <ctype.h>
#include <stdio.h>

int Precede(char op) //获取运算符的优先级
{
    switch (op)
    {
    case '+':
    case '-':
        return 1;
    case '*':
    case '/':
        return 2;
    case '(':
    case '@':
    default:
        return 0;
    }
}

bool Change(char *s1,char *s2){
    LStack S;
    Init_LStack(S);
    PushLStack(S,'@');
    int i=0,j=0;
    char ch = s1[i];
    LElemType e;
    while(ch!='@'){
        if(ch ==' '){
            ch = s1[++i];
        }else if(ch=='('){
            PushLStack(S,ch);
            ch = s1[++i];
        }else if(ch==')'){
            while(true){
                GetTop(S,e);
                if(e=='(')
                    break;
                PopLStack(S,e);
                s2[j++] = e;
                s2[j++] = ' ';
            }
            PopLStack(S,e);
            ch = s1[++i];
        }else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){
            GetTop(S,e);
            while(Precede(e)>=Precede(ch)){
                s2[j++] = e;
                s2[j++] = ' ';
                PopLStack(S,e);
                GetTop(S,e);
            }
            PushLStack(S,ch);
            ch = s1[++i];
        }else{
            // 数字及小数点
            while(isdigit(ch)||ch=='.'){
                s2[j++] = ch;
                ch = s1[++i];
            }
            s2[j++] = ' ';
        }
    }
    PopLStack(S,e);
    while(e!='@'){
        if(e=='(')
            return false;
        else{
            s2[j++] = e;
            PopLStack(S,e);
        }
    }
    s2[j++] = ' ';
    s2[j++] = '@';
    s2[j++] = '\0';
    return true;
}

main.cpp(注意不是main.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "listack.h"

bool Change(char *s1,char *s2);

int main(){

    char s1[] = "16-9*(4+3)+2@",s2[100];
    Change(s1,s2);
    printf("%s\n",s2);
    return 0;
}

运行结果如下:

注意结果中带有@符号,只是为了便于接下来的求值,这里不再一一赘述了。

posted @ 2022-07-04 18:32  坚持不懈的大白  阅读(402)  评论(0编辑  收藏  举报
@format