后缀表达式通过栈实现表达式树
2017-02-14 21:29
393 查看
通过栈来实现将后缀表达式变成表达式树,通过先序遍历和中序遍历来转换成前缀和中缀表达式,在下面用全局变量或者静态变量来保存递归中得到的数据,这样就可以来保存表达式树的几种方式。
![](https://img-blog.csdn.net/20170313214227566)
![](https://img-blog.csdn.net/20170313214233770)
通过栈不断将节点合并最终生成表达式树,首先遇到'1'到'9'将其都压入栈中遇到‘+’ ‘-’ ‘*’ ‘/’就取出2个节点合并成一个节点,这样不断将数据合并,由于后缀表达式树本身包含了先后运算顺序,所以不需要括号之类的字符。前面写道过如何将中缀表达式(包含括号等)转换成后缀表达式。并计算整个表达式的值,这里由于表达式的转换问题只能转换1位的表达式。多位的话(如123无法区分是12和3还是1和23以及将字符转换成2位数),所以对于超过1位的将会存在一些问题。
//函数接口
//接口函数定义
//main函数入口
//实现结果
通过栈不断将节点合并最终生成表达式树,首先遇到'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; }
//实现结果
相关文章推荐
- 数据结构实验之栈六:下一较大值(二)
- 数据结构之二叉树
- 链表删除,反序操作等
- 数据结构之二叉树遍历的递归算法
- 数据结构---栈:一般算术表达式
- 数据结构实验之栈:行编辑器
- [mmc subsystem] mmc core(第二章)——数据结构和宏定义说明
- 数据结构--栈的基本操作
- 【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)
- 数据结构实验之串一:KMP简单应用
- 简单说一说数据结构——栈
- 数据结构及在Android中的应用
- 输出n阶魔方矩阵
- 数据结构之二叉树(遍历、建立、深度)
- Amazon Dynamo论文解读 - Merkle Tree的使用
- Java 数据结构 --> Properties 接口
- 【数据结构】之 线性表详解
- 《数据结构》严蔚敏版(java解)——第三章 栈和队列02 链式栈操作
- Java 数据结构 --> Hashtable 接口
- 数组、链表、堆栈和队列