思想
1.将输入的中缀表达式转化为后缀表达式。
2.用后缀表达式构造表达式二叉树。
3.检验二叉树是否创建成功。采用的是递归遍历,三种常规遍历先中后序遍历。
4.后缀表达转换:
优先级±</<^<(),当a中的字符为数字时直接放入b,为运算符时根据优先级入栈(S1),优先级高的位于栈顶。()运算符较为特殊,当遇到左括号时入栈,直到遇到右括号才出栈,且出栈是括号里的所有元素。
5.后缀表达式建树过程:
假设输入:(a+b)(c*(d+e)),转为后缀表达式为:ab+cde**,根据后缀表达式建立二叉树。
(1)遇到ab。将指向两节点的指针压入栈中。
(2)遇到操作数+,弹出指向两元素的指针,形成一棵树,将指向该树的指针压入栈中
(3)遇到cde,将指针压入栈中。
(3)遇到操作数+,出栈两个指针,生成新树入栈。
(4)同上
(5)同上
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define Empty -1
#define MaxSize 50//可输入50个字符
//存放字符的栈
typedef struct StackRecord {
int Capacity;
int TopofStack;
char* array;//指针变量
}*Stack;
//树结构声明
typedef struct TreeNode* Tree;
typedef struct TreeNode {
Tree left;
Tree right;
char data;
}*Bintree;
//存放结点的栈
typedef struct StackRecord1 {
int TopofStack;
Bintree *array;//定义Bintree类型的指针变量,因为该栈存放的是Bintree类型的结点
}*Stack1;
///对栈的操作
int IsEmpty(Stack S);//判断栈是否为空
int IsFull(Stack S);//判断栈是否已满
Stack CreateStack(int CHARDigits);//字符栈的创建
void Push(Stack S, char x);//入栈
int Top(Stack S, char* element);//出栈
void Pop(Stack S, char* element);//置空栈
int IsEmpty(Stack S) {
return S->TopofStack == Empty;
}
int IsFull(Stack S) {
return S->TopofStack == S->Capacity;
}
//创建字符栈
Stack CreateStack(int CHARDigits) {
Stack S;
S = (Stack)malloc(sizeof(struct StackRecord));
if (S == NULL) {
printf("out of space");
return 0;
}
S->array = (char*)malloc(sizeof(int) * CHARDigits);
if (S->array == NULL) {
printf("out of space");
return 0;
}
S->Capacity = CHARDigits;
S->TopofStack = Empty;
return S;
}
//创建树结点栈
Stack1 CreateStack1(int CHARDigits) {
Stack1 S;
S = (Stack1)malloc(sizeof(struct StackRecord1));
if (S == NULL) {
printf("out of space");
return 0;
}
S->array = (Bintree*)malloc(sizeof(struct StackRecord1) * CHARDigits);
if (S->array == NULL) {
printf("out of space");
return 0;
}
S->TopofStack = -1;
return S;
}
//入栈
void Push(Stack S, char x) {
if (IsFull(S)) {
printf("stack is full");
}
else
S->array[++S->TopofStack] = x;
}
//出栈
void Pop(Stack S, char* element) {
if (IsEmpty(S))
printf("stack is empty");
else
*element = S->array[S->TopofStack--];
}
int Top(Stack S, char* element) {
if (!IsEmpty(S)) {
*element = S->array[S->TopofStack];
return 1;
}
else {
printf("empty stack\t");
return 0;
}
}
//中缀转后缀
void TransLate(Stack S, char a[], char b[]) {
char ch, element = NULL;
int i = 0, j = 0;
ch = a[i++];
while (ch != '\0') {
switch (ch) {
case'('://左括号出现,右括号不出现就有符号入栈
Push(S, ch);
break;
case')'://右括号出现,括号里面的所有符号出栈
while (Top(S, &element) && element != '(') {
Pop(S, &element);
b[j++] = element;
}
Pop(S, &element);//将左括号出栈
break;
case'+':
case'-'://加减的优先级最低压入栈底
while (!IsEmpty(S) && Top(S, &element) && element != '(') {
Pop(S, &element);
b[j++] = element;
}
Push(S, ch);
break;
case '*':
case '/'://乘除优先级比加减高遇到加减入栈,其他情况元素出栈再入栈
while (!IsEmpty(S) && Top(S, &element) && element == '/' || element == '*' || element == '^') {
Pop(S, &element);
b[j++] = element;
}
Push(S, ch);
break;
case '^'://次幂优先级大于乘除,遇到'^'出栈再入栈,其他情况入栈
while (!IsEmpty(S) && Top(S, &element) && element == '^') {
Pop(S, &element);
b[j++] = element;
}
Push(S, ch);
break;
case' ':
break;
default://数字的字符串优先级最低,不入栈直接输出
while (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
b[j++] = ch;
ch = a[i++];
}
i--;
}
ch = a[i++];
}
while (!IsEmpty(S))//剩余字符输出
{
Pop(S, &element);
b[j++] = element;
}
b[j] = '\0';
}
//构造一棵树
Bintree PosTree(Stack1 S2, char b[]) {
Bintree p, root;
int i = 0;
while (b[i] != '\0') {
if (b[i] == '+' || b[i] == '-' || b[i] == '*' || b[i] == '/' || b[i] == '^') {
p = (Bintree)malloc(sizeof(struct TreeNode));
if (p == NULL) {
printf("out of space");
return 0;
}
p->data = b[i];
p->right = S2->array[S2->TopofStack--];//先右节点,在左节点
p->left = S2->array[S2->TopofStack--];
S2->array[++S2->TopofStack] = p;
b[i++];
}
else {
p = (Bintree)malloc(sizeof(struct TreeNode));
p->data = b[i];
p->left = NULL;
p->right = NULL;
S2->array[++S2->TopofStack] = p;
b[i++];
}
}
root = S2->array[S2->TopofStack--];
printf("Create success!\n");
return root;
}
//先序遍历
void Preorder(Bintree p)
{
if (p != NULL)
{
printf("%c", p->data);
Preorder(p->left);
Preorder(p->right);
}
}
//中序遍历
void Inorder(Bintree p)
{
if (p != NULL)
{
Inorder(p->left);
printf("%c", p->data);
Inorder(p->right);
}
}
//后序遍历
void Postorder(Bintree p)
{
if (p != NULL)
{
Postorder(p->left);
Postorder(p->right);
printf("%c", p->data);
}
}
int main() {
Stack S1;
Stack1 S2;
Bintree p;
char a[MaxSize], b[MaxSize];
int num;
printf("输入算术表达式:");
gets(a);
printf("infix is :%s\n", a);//输出中缀
num = strlen(a);
S1 = CreateStack(num);//根据字符串长度建栈
S2 = CreateStack1(num);
TransLate(S1, a, b);
printf("postfix is :%s\n", b);//输出后缀
p = PosTree(S2, b);
printf("Preorder is:");//先序遍历
Preorder(p);
printf("\n");
printf("Inorder is:");//中序遍历
Inorder(p);
printf("\n");
printf("Postorder is:");//后序遍历
Postorder(p);
printf("\n");
return 0;
}
结果: