数据结构(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;
}
运行结果如下:
注意结果中带有@符号,只是为了便于接下来的求值,这里不再一一赘述了。