这三种算法都借助栈,中缀转后缀是符号入栈,其他是数值入栈。
中缀转后缀思路:当遇到操作符的时候,放入栈中。栈代表挂起的操作符。遇到左括号时入栈,如果见到右括号,就将栈元素弹出,直到遇到左括号,弹出但不输出。
当遇到其他符号(‘+’, ‘*’, ‘(’),则从栈中弹出栈元素直到发现优先级更低的元素为止。‘(’优先级最高,除非遇到')',否则不出栈。之后当从战中弹出这些元素后,将当前元素入栈。
void zhongtohou(char *exp, char *houexp)
{
char *p;
char *pb = houexp;
stack stk;
init_stack(&stk);
for (p = exp; *p != '\0'; p++)
{
char c;
switch (*p)
{
case '+':
case '-':
while (!empty(&stk))
{
c = top(&stk);
if (c == '*' || c == '+' || c == '-' || c == '/')
{
pop(&stk);
printf("%c ", c);
*pb++ = c;
}
else
break;
}
push(&stk, *p);
break;
case ')':
while (!empty(&stk))
{
c = top(&stk);
if (c != '(')
{
printf("%c ", c);
*pb++ = c;
pop(&stk);
}
else
break;
}
pop(&stk);
if (c != '(')
printf("小括号匹配错误\n");
break;
case '*':
case '(':
case '/':
push(&stk, *p);
break;
default:
if (isalnum(*p))
{
printf("%c ", *p);
*pb++ = *p;
}
else
printf("wrong char\n");
break;
}
}
while (!empty(&stk))
{
printf("%c ", top(&stk));
*pb++ = top(&stk);
pop(&stk);
}
printf("\n");
}
后缀求值与后缀构造表达式树的思路相似,都是遇到元素入栈,遇到操作符,出栈栈顶两个元素,求值是计算值,并将计算后的值入栈,而表达式树是在构造一个新的符号节点,并将这两个元素作为左右孩子,然后将这个子树入栈,最后变成一棵树。
具体思路:
后缀表达式求值:当遇到一个数时,压入栈中,在遇到一个操作符时就作用于从该栈弹出的两个数上,在将所得结果入栈,最后栈中元素即为表达式值。
void exp_value(char *exp)
{
stack stk;
init_stack(&stk);
int a, b, val;
char *p = exp;
while (*p != '\0')
{
if (isdigit(*p))
push(&stk, *p);
else if (*p == '+' || *p == '-' || *p == '*' || *p == '/')
{
a = pop(&stk)-'0';
b = pop(&stk)-'0';
printf("%d %d\n", a, b);
switch (*p)
{
case '+':
val = a+b;
break;
case '-':
val = a-b;
break;
case '*':
val = a*b;
break;
case '/':
val = a/b;
break;
default:
break;
}
push(&stk, val+'0');
}
p++;
}
printf("表达式的值是: %d\n", val);
}
后缀表达式构造表达式树:将后缀表达式一个一个读入字符。如果是数,就建立一个单节点树并将它推入栈中。如果符号是操作符,则从栈中弹出两棵树T1,T2,并形成一棵新的树,该树的跟就是操作符,左右孩子分别是T1,T2.然后将这棵新树的指针入栈。
template <typename Object>
struct BinaryNode
{
Object element;
BinaryNode<Object> *left;
BinaryNode<Object> *right;
};
typedef struct BinaryNode<char> Node;
typedef struct BinaryNode<char>* pNode;
pNode houtoexp(char *exp)
{
char *p = exp;
stack<pNode> stk;
pNode bnode;
while (*p != '\0')
{
//如果是数字或字母,构造节点,进栈
if (isalnum(*p))
{
bnode = new Node;
bnode->element = *p;
bnode->left = bnode->right = NULL;
stk.push(bnode);
}
else
{
pNode lnode = stk.top();
stk.pop();
pNode rnode = stk.top();
stk.pop();
bnode = new Node;
bnode->element = *p;
bnode->left = rnode;
bnode->right = lnode;
stk.push(bnode);
}
p++;
}
return bnode;
}