您的位置:首页 > 理论基础 > 数据结构算法

后缀表达式通过栈实现表达式树

2017-02-14 21:29 393 查看
通过栈来实现将后缀表达式变成表达式树,通过先序遍历和中序遍历来转换成前缀和中缀表达式,在下面用全局变量或者静态变量来保存递归中得到的数据,这样就可以来保存表达式树的几种方式。





通过栈不断将节点合并最终生成表达式树,首先遇到'1'到'9'将其都压入栈中遇到‘+’ ‘-’ ‘*’ ‘/’就取出2个节点合并成一个节点,这样不断将数据合并,由于后缀表达式树本身包含了先后运算顺序,所以不需要括号之类的字符。前面写道过如何将中缀表达式(包含括号等)转换成后缀表达式。并计算整个表达式的值,这里由于表达式的转换问题只能转换1位的表达式。多位的话(如123无法区分是12和3还是1和23以及将字符转换成2位数),所以对于超过1位的将会存在一些问题。

//函数接口

#ifndef _TREESTACK_H
#define _TREESTACK_H
typedef struct node
{
union //使用联合 共用首地址 节省物理内存
{
char operator;
int data;
};
struct node *lchild;
struct node *rchild;
}TreeNode;
typedef struct treestack
{
TreeNode **Base; //二维指针来保存指向指针的地址
TreeNode **Top;
int Capacity;
}TreeStack;
int InitStack(TreeStack *TreeSta,int length);
int Push(TreeStack *TreeSta,TreeNode *TNode);
TreeNode *Pop(TreeStack *TreeSta);
int IsEmpty(TreeStack *TreeSta);
int DestoryStack(TreeStack *TreeSta);
TreeNode *InitTreeInStack(char *str,TreeStack *Stackpt);
void VisitNode(TreeNode *p);
void PostOrder(TreeNode *p);
void InOrder(TreeNode *p);
void PreOrder(TreeNode *p);
void DestoryTree(TreeNode *p);
#endif


//接口函数定义

#include <stdio.h>
#include <stdlib.h>
#include "treestack.h"
#define MAX 100
static void PrintNode(TreeNode *p);
char buf[10];
int j=0; //使用全局变量来记录数据个数 或者在函数内用static用
int InitStack(TreeStack *TreeSta,int length) //栈的基本实现操作
{
if(length>MAX)
return 0;
TreeSta->Base=TreeSta->Top=(TreeNode **)malloc(length*sizeof(TreeNode *));
TreeSta->Capacity=length;
return 1;
}
int Push(TreeStack *TreeSta,TreeNode *TNode)
{
if((TreeSta->Top-TreeSta->Base)>=TreeSta->Capacity)
return 0;
*(TreeSta->Top++)=TNode;
return 1;
}
TreeNode *Pop(TreeStack *TreeSta)
{
if(TreeSta->Top==TreeSta->Base)
return NULL;
return *(--TreeSta->Top);
}
int IsEmpty(TreeStack *TreeSta)
{
if(TreeSta->Top==TreeSta->Base)
return 1;
else
return 0;
}
TreeNode *InitTreeInStack(char *str,TreeStack *p)
{
int i=0;
TreeNode *current;
TreeNode *left,*right;
while(str[i])
{
if(str[i]>='0'&&str[i]<='9')//判断是否为数据 将数据压入栈中
{
current=(TreeNode *)malloc(sizeof(TreeNode));
current->data=str[i]-'0';
current->lchild=NULL;
current->rchild=NULL;
Push(p,current);
}
else//为运算符 取出2个数据将其合并 并压入栈中
{
current=(TreeNode *)malloc(sizeof(TreeNode));
current->operator=str[i];
right=Pop(p);
left=Pop(p);
current->lchild=left;
current->rchild=right;
Push(p,current);
}
i++;
}
return Pop(p);
}
static void PrintNode(TreeNode *p)
{
if(p->lchild==NULL&&p->rchild==NULL)
printf("%d",p->data);
else
printf("%c",p->operator);
}
static char OutPut(TreeNode *p)
{
if(p->lchild==NULL&&p->rchild==NULL)
return (p->data+'0');
else
return p->operator;
}
void VisitNode(TreeNode *p)
{
PrintNode(p);
}
void PostOrder(TreeNode *p)//三种遍历方式
{
if(p!=NULL)
{
PostOrder(p->lchild);
PostOrder(p->rchild);
VisitNode(p);
buf[j++]=OutPut(p);
}
}
void InOrder(TreeNode *p)
{
if(p!=NULL)
{
InOrder(p->lchild);
VisitNode(p);
InOrder(p->rchild);
}
}
void PreOrder(TreeNode *p)
{
if(p!=NULL)
{
//buf[j++]=OutPut(p);  //使用全局变量j保存数据内容
VisitNode(p);
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void DestoryTree(TreeNode *p)
{
if(p!=NULL)
{
DestoryTree(p->lchild);
DestoryTree(p->rchild);
free(p);
}
}
int DestoryStack(TreeStack *TreeSta)
{
if(TreeSta->Base==NULL)
return 0;
free(TreeSta->Base);
TreeSta->Base=TreeSta->Top=NULL;
buf[j]='\0';
printf("\n%s",buf);
return 1;
}


//main函数入口

#include <stdio.h>
#include <string.h>
#include "treestack.h"
int main(void)
{
TreeNode *thread;
TreeStack TStack;
char buf[100];
scanf("%s",buf);
InitStack(&TStack,strlen(buf));
thread=InitTreeInStack(buf,&TStack);
printf("PostOrder:");
PostOrder(thread);
printf("\n");
printf("InOrder:");
InOrder(thread);
printf("\n");
printf("PreOrder:");
PreOrder(thread);
printf("\n");
DestoryStack(&TStack);
DestoryTree(thread);
return 0;
}


//实现结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息