⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree_exp.cpp

📁 数据结构课程中利用树进行表达式求值方法
💻 CPP
字号:
#include<stdio.h>
#include<stdlib.h>
#include<process.h>   
#include<conio.h>

#define STACK_INIT_SIZE 100   //存储空间初始分配量
#define	STACKINCREMENT 10   //存储空间分配增量

typedef int ElemType;

typedef struct BiTNode
{
	ElemType data;
	struct BiTNode *lchild,*rchild;
	struct BiTNode *next;
}BiTNode,*BiTree;

typedef struct 
{
	BiTree base;
	BiTree top;
	int stacksize;
}LinkStack;

LinkStack S;
LinkStack PTRS;
char OP[7]={'+','-','*','/','(',')','#'};
char op[4]={'+','-','*','/'};

void wait()    
{
	printf("\n\n按任意键继续\n");
	getch();
}

int StackEmpty(LinkStack &S)
{//判断栈是否为空
	if(S.base == S.top)
		return 1;
	else
		return 0;
}

int InitStack(LinkStack &S)
{//构造一个空栈,初始化
	S.base = S.top = (BiTree)malloc(sizeof(BiTNode));  
	if(!S.base)
		return 0;  //存储分配失败
	S.top->next = NULL;
	return 1;
}

char Push(LinkStack &S, char e)
{//数据压栈
	BiTNode *p;
	p = (BiTNode *)malloc(sizeof(BiTNode));
	p->data = e;  //将传入的数据压栈
	p->next = S.top;
	S.top = p;
	return e;
}

char Pop(LinkStack &S, char &e)
{
	BiTNode *p;
	if(StackEmpty(S))
	{
		return '0';//空栈
	}
	else
	{//当栈非空,
		p = S.top;
		S.top = p->next;
	}
	e = p->data;
	return e;
}

char GetTop(LinkStack &S,char &e)
{
	if(StackEmpty(S))
	{
		return '0';
	}
	else
	{
		e = (S.top)->data;
	}
	return e;
}

BiTNode *Pop(LinkStack &S,BiTNode *p)
{
	if(StackEmpty(S))
	{
		printf("空栈");
		return NULL;
	}
	else
	{//当栈非空
		p = S.top;
		S.top = p->next;
		return p;
	}
}

BiTNode *Push(LinkStack &S, BiTNode *p)
{//数据压栈
	p->next = S.top;
	S.top = p;
	return p;
}

void DestroyStack(LinkStack &S)
{
	BiTNode *p;
	while(!StackEmpty(S))
	{
		p = S.top;
		S.top = p->next;
		free(p);
	}
}

int IN(char c,char *op)//比较字符是否为运算符,是则返回1,否则0
{
        int i=0;
        while(i < 7)
        	if(c == op[i++])
				return 1;
        return 0;
}

int precede[7][7]={//检查运算符排序方法
    1,1,3,3,3,1,1,
    1,1,3,3,3,1,1,
    1,1,1,1,3,1,1,
    1,1,1,1,3,1,1,
    3,3,3,3,3,2,0,
    1,1,1,1,0,1,1,
    3,3,3,3,3,0,2,
};

int Precede(char op,char c)//比较运算符的优先级
{
        int pos_op;
        int pos_c;
        int i;
        for(i=0;i<7;i++)
        {
                if(op==OP[i]) pos_op=i;
                if(c==OP[i]) pos_c=i;
        }
        switch(precede[pos_op][pos_c])
        {
                case 1:return 1;//优先级高
				case 2:return 0;//优先级低
                case 3:return 0;
				default:return 0;
        }
}

//建叶子结点的算法为:
void CrtNode(BiTree T,int ch)
{
	if (!(T = new BiTNode))
		exit(0);//OVERFLOW
	T->data = ch;
	T->lchild = T->rchild = NULL;
	T =	Push(PTRS,T);
}

//建子树的算法为:
void CrtSubtree(BiTree T,char c)
{
	BiTNode *rc,*lc;
	rc = new BiTNode;
	lc = new BiTNode;
	if (!(T= new BiTNode))
		exit(0);//OVERFLOW
	T->data = c;
	rc = Pop(PTRS,rc);
	T->rchild = rc;
	lc = Pop(PTRS,lc);
	T->lchild = lc;
	T = Push(PTRS,T);
}

BiTree CrtExptree(char* exp)
{// 建立由合法的表达式字符串 exp 确定的只含二元运算符的 
 // 非空表达式树,返回其存储结构二叉链表的根结点指针
 	BiTree t;
	t = new BiTNode;
	char *p,ch,c;
	char pc;  //当前字符的后一个字符
	int st = 0;  //暂存要进行转换的数值
 	InitStack(S);
	Push(S,'#'); // S为暂存运算符的栈
	InitStack(PTRS);	// PTRS为暂存子树根指针的栈
	p=exp;  //表达式字符串 
	ch=*p;  //取一个字符 
	if(!(IN(ch,OP)))
	{
		pc = *(p+1);  //当第一个字符非运算符,让pc指向它的下一个字符
	}
	while(!(GetTop(S,c)=='#'&& ch=='#')) //取字符还未结束 
	{
		if(!IN(ch,OP))  //判断取入的是否是运算符 
		{
			if(st == 0)
				st = ch-48; //ASCII->int
			if(!IN(pc,OP))
			{
				st = st*10+(pc-48); //多位数字进行转化
			}
			if(IN(pc,OP))
			{
				CrtNode(t,st);
				st = 0;  //st已建立叶子节点,内容清空
			}
		}
		else
		{//是运算符 
			switch(ch) 
			{
				case'(': ch = Push(S, ch); break; //是左括号,则压入栈 
				case')':
				{
					c = Pop(S,c);  //碰到右括号,将栈内数据弹出 
					while (c!='(')
					{
						CrtSubtree(t,c);
						c = Pop(S,c);
					} // 建子树直至运算符的栈顶为'('
						break;
				}
				default:
				{//非左右括号,取得运算符栈栈顶元素,与取得的字符的优先级进行比较
					while (GetTop(S,c) && (Precede(c,ch))) 
					{
						CrtSubtree(t,c);
						c = Pop(S,c);
						if(GetTop(S,c)=='#'&& ch=='#')
							break;
					}// 建子树直至运算符栈顶运算符的优先数低
					if(ch != '#')//还未到表达式末尾则继续取一个字符压栈 
						ch = Push(S,ch);
					break;
				}// default
			} // switch
		} // else
		if(ch != '#')
		{
			p++;
			ch = *p;
			pc = *(p+1);
		}
	} // while 循环结束,所有字符处理完毕。
	c = Pop(S,c);//运算符栈 
	t = Pop(PTRS,t);//子树根节点栈 
	DestroyStack(S);//销毁栈 
	DestroyStack(PTRS);
	return t;
} // CrtExptree 

void preorder(BiTree &T)
{//先序遍历二叉树的递归算法
	if(T)
	{
		if(T->lchild!=NULL&&T->rchild!=NULL)
			printf("%c",T->data);
		else
			printf("%d",T->data);
		preorder(T->lchild);  //访问左孩子节点
		preorder(T->rchild);  //访问右孩子节点
	}
}

void midorder(BiTree &T)
{//中序遍历二叉树的递归算法
	if(T)
	{
		midorder(T->lchild);  //访问左孩子节点
		if(T->lchild!=NULL&&T->rchild!=NULL)
			printf("%c",T->data);
		else
			printf("%d",T->data);
		midorder(T->rchild);  //访问右孩子节点
	}
}

void postorder(BiTree &T)
{//后序遍历二叉树的递归算法
	if(T)
	{
		postorder(T->lchild);  //访问左孩子节点
		postorder(T->rchild);  //访问右孩子节点
		if(T->lchild!=NULL&&T->rchild!=NULL)
			printf("%c",T->data);
		else
			printf("%d",T->data);
	}
}

int Operate(int a,char P,int b)
{//运算函数,返回运算结果
	switch(P)
	{
		case '+':return a+b;
		case '-':return a-b;
		case '*':return a*b;
		case '/':
		{
			if(b==0)
			{
				printf("\n错误,除数不能为0!\n");
				wait();
				exit(0);
			}
			else
				return a/b;
		}
		default:return 0;
	}
}

int Value(BiTree &t,char tl,char tr)
{//对表达式树进行运算,返回结果
	char P;
	int A,B,V;
	A=tl;
	B=tr;
	P=t->data;
	if(!IN(P,OP))
		return ((int)P);
	if (IN(tl,OP))
		A=Value(t->lchild,t->lchild->lchild->data,t->lchild->rchild->data);
	if (IN(tr,OP))
		B=Value(t->rchild,t->rchild->lchild->data,t->rchild->rchild->data);
	V=Operate(A,P,B);//调用运算函数
	return V;
}

int main()
{
	char exp[100];
	BiTree t;
	int f=0,j,b = 0,i;
	printf("-----------------第三章 利用树进行表达式求值------------------\n");
	printf("\n欢迎使用本软件!\n");
	printf("说明:请先输入一个算数表达式,以'#'为结束符。程序将输出最后计算结果。\n");
	printf("\n请输入一个表达式:");
	scanf("%s",exp);
	if(exp[0] == '#')
		printf("\n表达式为空!\n");
	else
	{	
		for(i = 0;exp[i]!='\0';i++)
		{
			if(exp[i]=='(')
				b++;
			if(exp[i]==')')
				b--;
		}
		for(i = 0;exp[i]!='\0';i++)
		{
			if(exp[i]=='#')
			{
				f = 1;
				j = i;
				break;
			}
		}
		if(f==1)
		{
			if(IN(exp[j-1],op))
				f=0;
		}
		for(i = 0;exp[i]!='\0';i++)
		{
			if(IN(exp[0],op)||(IN(exp[i],op)&&IN(exp[i+1],op)))
			{
				f = 0;
				break;
			}
		}
	
		if(f == 0||b != 0)
			printf("\n表达式输入错误!\n");
		else
		{
			t = CrtExptree(exp);
			printf("\n前缀表达式:");
			preorder(t); 
			printf("\n\n中缀表达式:");
			midorder(t); 
			printf("\n\n后缀表达式:");
			postorder(t);
			printf("\n");
			if(t->lchild!=NULL&&t->rchild!=NULL)
			{
				printf("\n表达式的值为:%d\n",Value(t,t->lchild->data,t->rchild->data));
			}
			else
				printf("\n表达式的值为:%d\n",t->data);
		}
	}
	wait();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -