表达式树

表达式树

 

二叉树用来存储表达式,

例如下面一颗二叉树:

 

插叙下:

二叉树的遍历方式 


前序遍历;
中序遍历;
后序遍历;


解释:这里所谓的 前序,中序,后序 的意思
是 整个二叉树遍历顺序相对于 root 节点 
前序 也就是先遍历root节点,其次左节点,最后是 右节点 


      

这是一颗 表达式树 , 而后序遍历 得到表达式: ab+cde+d** ;

 

那么很多时候我们会根据 这种表达式 建立 表达式树(二叉树)

 

 假使 根据 表达式 ab+cde** 建立表达式树 算法如下:

 

1.        依次读取表达式;

2.        如果是操作数,将其压入栈中;

3.        如果是操作符,弹出栈中两个元素,第一个作为右子节点,第二个作为左子节点,将操作符压入栈中;

 

 

  下面就 把 ab+cde** 演变成 表达式树

 

整个创建表达式树的过程如下:

再观察一个例子:

 设输入为ab+cde+**

 

前两个符号是操作数,因此创建两棵单结点树并将指向它们的指针压入栈中。

 

 

接着,"+"被读入,因此指向两棵树的指针被弹出,形成一棵新的树,并将指向它的指针压入栈中。

 


然后,c,d和e被读入,在单个结点树创建后,指向对应的树的指针被压入栈中。

 

 

接下来读入"+"号,因此两棵树合并。

 

 

继续进行,读入"*"号,因此,弹出两棵树的指针合并形成一棵新的树,"*"号是它的根。

 

 

最后,读入一个符号,两棵树合并,而指向最后的树的指针被留在栈中。

 



下面我把代码贴出来 看看 实现方式 :


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define Max 20

typedef struct node
{
	
	union
	{
		char op;	//操作符
		int od;		//操作数
	};

	struct node * lChild ;//左孩子
	struct node * rChild; //右孩子
	
} Node;


typedef struct stack
{	
	int size;
	Node * nodes[Max];
	
} Stack ;

Stack * CreateStack()
{

	Stack * stack = (Stack *)malloc(sizeof(Stack));
	
	stack->size = 0;

	return stack;

}

int Push(Stack * stack,Node * node)
{
	if(stack->size >= Max)//stack full
		return 0;

	if(stack == NULL || node == NULL)
		return ;


	stack->nodes[stack->size] = node;

	stack->size++;
		
	return 1;
}

Node * Pop(Stack * stack)
{
	if(stack == NULL) return NULL;
	
	if(stack->size ==0)
		return NULL;
 
	Node * node;
	
	stack->size--;
    node = stack->nodes[stack->size];
	
	return node;
	
}


Stack * CreateExpressionTree(Stack * stack, char * expression)
{
	

	int i=0;
	int len = strlen(expression);
	char * str = expression;
	

	for(;i<len;i++)
	{
         
		 char c = *(str+i); 
		 
		 Node * node = (Node *)malloc(sizeof(Node));

		 if(c == '+' || c=='-' ||c=='*' ||c=='/')
		 {  

			 node->op = c;

				
			 Node * rightChild = Pop(stack);
			 Node * leftChild = Pop(stack);

				
			 node->rChild = rightChild;
			 node->lChild = leftChild;
			
		 }
		 else
		 {
			 node->od = (int)c;

			 node->rChild = NULL;
			 node->lChild = NULL;
			 
		 }

		 Push(stack,node);

	}
	
	return stack;
}

//打印单个 节点
void PrintNode(Node * node)
{
 
	if(node->lChild == NULL && node->rChild)
		putchar((char)node->od);
	else
		putchar(node->op);
}

//再次声明,不作健壮性判断;
//后序遍历 节点
void OrderPost(Node * node)
{

		if(node==NULL)
			return ;
		
		OrderPost(node->lChild);
		OrderPost(node->rChild);
		PrintNode(node);
}


void OrderExpressionTree(Stack * stack)
{

	if(stack== NULL){
		puts("the tree is NULL");
		return ;
	}

	Node * top = Pop(stack);
	

	while(top!=NULL)
	{	
		OrderPost(top);
		top = Pop(stack);
    }
}



int main(int argc, char *argv[])
{

	char * expression = "ab*cde+**";
	
	Stack * tree = CreateStack();

	tree = CreateExpressionTree(tree,expression);

	OrderExpressionTree(tree);
	
	return 0;
}


 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值