后缀表达式转二叉树结构

前言:后缀表达式转二叉树结构学习和实现笔记

上个星期在这篇笔记中记录了如果通过栈来实现中缀转后缀表达式以及如何进行运算栈中的结果

实现中缀转后缀表达式以及运算的笔记文章:https://www.cnblogs.com/zpchcbd/p/16083724.html

今天的话继续来学习如何在后缀表达式中转换为二叉树的结构,转换二叉树的思路参考:https://blog.csdn.net/qq_26849233/article/details/72910010

为什么要将表达式转换为二叉树的结构

布吉岛啊,我只是看到一篇文章说将表达式转换为二叉树的形式,能够通过前中后序遍历来获得对应的前中后缀算术表达式,前缀和后缀都不需要考虑括号的问题,但是中缀表达式应该是需要考虑括号的问题的,但是具体的我不太懂,以后知道了再来补上好了

实现后缀表达式转换二叉树

后缀表达式的特点是:一定以两个操作数开始,且以操作符结尾,形如ab+cde+**就是一个后缀表达式。

在表达式树中的特点就是:树的树叶是操作数(常数或变量),而其他节点为操作符。由于一般的操作符都是二元的,所以表达式树一般的都是二叉树。

代码实现如下

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 99

typedef int Status;
typedef int ElemType;

typedef struct _TreeNode{
	char nodeData;
	struct _TreeNode* pLeftTreeNode;
	struct _TreeNode* pRightTreeNode;
}TreeNode, *PTreeNode;

typedef struct _SqStack
{
	int iInitSize;
	int iCurrentLength;
	ElemType* pStack;
	ElemType* pTop;
	ElemType* pBottom;
}SqStack, *PSqStack;

Status initStack(SqStack* pSqStack, int iSize)
{
	pSqStack->pStack = malloc(sizeof(int)*iSize);
	if (checkMemoryValidAddress((void*)pSqStack->pStack) == ERROR) return ERROR;
	pSqStack->iInitSize = iSize;
	pSqStack->pBottom = pSqStack->pTop = pSqStack->pStack;
	pSqStack->iCurrentLength = 0;
	return OK;
}

Status pushElem(SqStack* pSqStack, ElemType elem)
{
	// juege between top and length
	if (pSqStack->iCurrentLength == pSqStack->iInitSize)
		return ERROR;
	*pSqStack->pTop++ = elem;
	pSqStack->iCurrentLength++;
	return OK;
}

ElemType popElem(SqStack* pSqStack)
{
	ElemType elem;
	if (pSqStack->pTop == pSqStack->pBottom)
		return ERROR;
	elem = *--pSqStack->pTop;
	pSqStack->iCurrentLength--;
	return elem;
}

// 获取栈顶元素
ElemType getHeadElem(SqStack* pSqStack)
{
	ElemType* pTempTop = pSqStack->pTop;
	return *--pTempTop;
}

Status checkStackEmpty(SqStack* pSqStack)
{
	if (pSqStack->pTop == pSqStack->pBottom)
		return OK;
	else
		return ERROR;
}

TreeNode* getBinaryTreeFromExpression()
{
	SqStack sqStack;
	char pPostfixExpression[MAXSIZE] = { 0 };
	char* pPostChar = NULL;
	TreeNode* pTreeNode = NULL;
	TreeNode* pTreeNodeOpera1 = NULL;
	TreeNode* pTreeNodeOpera2 = NULL;
	int iSize;
	printf("Init Stack Size -> ");
	scanf("%d", &iSize);
	// 初始化栈结构
	initStack(&sqStack, iSize);
	// 初始化中缀表达式
	printf("Init PostfixExpression -> ");
	scanf("%s", pPostfixExpression);
	pPostChar = pPostfixExpression;
	// -----------对后缀表达式进行构造树-----------
	while (*pPostChar != '\0')
	{
		if (*pPostChar == '+' || *pPostChar == '-' || *pPostChar == '*' || *pPostChar == '/')
		{
			// 操作符的情况
			// 如果是操作符的情况,那么就需要弹出两个
			pTreeNodeOpera1 = (TreeNode*)popElem(&sqStack);
			pTreeNodeOpera2 = (TreeNode*)popElem(&sqStack);
			pTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
			memset(pTreeNode, 0, sizeof(TreeNode));
			pTreeNode->pRightTreeNode = pTreeNodeOpera1;
			pTreeNode->pLeftTreeNode = pTreeNodeOpera2;
			pTreeNode->nodeData = *pPostChar;
			// 然后再重新放置回去
			pushElem(&sqStack, (ElemType)pTreeNode);
			pTreeNode = NULL;
		}
		else if (*pPostChar >= 'a' && *pPostChar <= 'z') // 1位数进行测试
		{
			// 操作数的情况
			pTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
			memset(pTreeNode, 0, sizeof(TreeNode));
			pTreeNode->nodeData = *pPostChar;
			pushElem(&sqStack, (ElemType)pTreeNode);
		}
		pPostChar++;
	}
	
	pTreeNode = (TreeNode*)popElem(&sqStack);
	return pTreeNode;
}

void postOrder(TreeNode* pTreeNode)
{
	if (pTreeNode != NULL)
	{
		preOrder(pTreeNode->pLeftTreeNode);
		preOrder(pTreeNode->pRightTreeNode);
		printf("%c ", pTreeNode->nodeData);
	}
}


// 实现中缀转后缀表达式并且实现运算需要总共执行两步操作
// 第一步 -> 实现中缀转化后缀
// 第二步 -> 实现解析后缀表达式来进行计算结果
int main()
{
	// test -> 1+2-3*4/2+5
	TreeNode* pTreeNode = getBinaryTreeFromExpression();
	preOrder(pTreeNode);
	return 0;
}

测试数据:ab+cde+**

posted @ 2022-04-13 13:01  zpchcbd  阅读(381)  评论(0)    收藏  举报