二叉树实现运算符优先级算法,支持表达式前缀,中缀,后缀,层次,广义表输出

无聊小练一下数据结构,表达式求值 
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct BITNODE
{
int flag;            //0没用过,1数字节点,2符号节点
char sign;
    	float number;
    	struct BITNODE *lchild,*rchild;
}BitNode,*BiTree; 
typedef struct LINKLIST
{
    struct BITNODE *treeNode;
    struct LINKLIST *nextNode;
    struct LINKLIST *lastNode;
}linkNode,*LinkList;
/+, -, *, /, (, ),\0,//
int priority[7][7]={ 1, 1,-1,-1,-1, 1, 1,         //优先算符表
                        1, 1,-1,-1,-1, 1, 1,
                     1, 1, 1, 1,-1, 1, 1,
                     1, 1, 1, 1,-1, 1, 1,
                    -1,-1,-1,-1,-1, 0, 0,
                     1, 1, 1, 1, 0, 1, 1,
                    -1,-1,-1,-1,-1, 0, 0};
int stackTopBiTree=-1;                            //栈顶指针
int stackTopSign=-1;
BiTree stackB[100];
char stackC[100];
///


BiTree popB()                                     //进出栈函数
{
    return stackB[stackTopBiTree--];
}

void pushB(BiTree biTree)
{
     stackB[++stackTopBiTree]=biTree;
}
///
char popC()
{
     return stackC[stackTopSign--];
}
void pushC(char sign)
{
     stackC[++stackTopSign]=sign;
}

BiTree outList(LinkList &list)
{
    if(!list->nextNode) return NULL;
    if(!list->nextNode->nextNode) list->lastNode=list;        //如果全出完了把最后
     LinkList tempList;                                   //结点放在头结点
     BiTree tempTree;             
    tempList=list->nextNode;
    tempTree=list->nextNode->treeNode;
    list->nextNode=list->nextNode->nextNode;
    free(tempList);                                      //释放链表接点
     return tempTree;
}
void inList(LinkList &list,BiTree treeNode)
{
    LinkList listNode;                 
    listNode=(LinkList)malloc(sizeof(linkNode));
    listNode->treeNode=treeNode;                         //从最后一个进栈
     listNode->nextNode=NULL;
    listNode->lastNode=NULL;
    list->lastNode->nextNode=listNode;                   //链表最后一个指向下一个
     list->lastNode=listNode;                             //更新最后一个的位置             
}
void ccPrintTree(BiTree node)
{
     if(!node){
  	printf("空树!");
 	return;
     }
     LinkList list;
     list=(LinkList)malloc(sizeof(LinkList));
     list->nextNode=NULL;
     list->treeNode=NULL;
     list->lastNode=list;
 
     inList(list,node);
     BiTree temp;
     while(list->nextNode) {
         temp = outList(list);
  	if(temp->lchild) inList(list,temp->lchild);   //还有结点入栈
 	if(temp->rchild) inList(list,temp->rchild);
  	if(temp->flag==1)  printf("\t%f",temp->number);
  	else printf("\t%c",temp->sign);
     }
}
void InitHead(BiTree &L)                  //初始化树
{
    L=(BiTree)malloc(sizeof(BitNode));
    L->lchild=NULL;
    L->rchild=NULL;
    L->sign='\0';
    L->number=0;
    L->flag=0;
}
float reap(char *exp,int position1,int position2)   //获得两个算符之间的数字
{
     int pot=position1+1,i=0;               //pot是小数点的位置      
      float numHigh=0.0,numLow=0.0;          //存放数字的小数点之前和之后的数
      char *p=exp+position1+1;
     while((*(p+i)!='.')&&(pot!=position2)) {
 	 i++;
 	  pot++;
     }
     for(int j=0;j<pot-position1-1;j++){      //计算数字
           numHigh+=(*(p+j)-'0');
         numHigh*=10.0;
     }
     numHigh/=10.0;
     for(int k=0;k<position2-pot-1;k++) {    //小数部分的计算
      numLow+=(*(exp+position2-1-k)-'0');
          numLow/=10.0;
     }
     return numHigh+numLow;
}
BiTree CreatTreeNode(BiTree nodeA,char sign,BiTree nodeB)
{
     BiTree signNode;
     signNode=(BiTree)malloc(sizeof(BiTree));    //创建树接点
      signNode->lchild=nodeA;
     signNode->rchild=nodeB;
     signNode->sign=sign;
     signNode->flag=2;
     return signNode;
}
char Precede(char top,char follow)          //确定优先性函数
{
     int i=0,j=0;
     switch(top){
 	case '+': i=0; break;
 	case '-': i=1; break;
 	case '*': i=2; break;
 	case '/': i=3; break;
 	case '(': i=4; break;
         case ')': i=5; break;
 	case '\0': i=6; break;
 	default: printf("error\n");
 	}
     switch(follow){
 	case '+': j=0; break;
 	case '-': j=1; break;
         case '*': j=2; break;
         case '/': j=3; break;
 	case '(': j=4; break;
 	case ')': j=5; break;
 	case '\0': j=6; break;
 	default: printf("error\n");
 	}
     switch(priority[i][j]){
 	 case 0:  return '=';
 	 case 1:  return '>';
          case -1: return '<';
     }
     return 'e';
}
void InitExpTree(BiTree &L)
{
         InitHead(L);                      
         printf("please input the express:");
 	char *exp=(char*)malloc(sizeof(char)*255);
 	scanf("%s",exp);                     //获得表达式
 	int haveNum=0,i=0;
 	char sign;
         int position1=-1,position2=1;        //记录符号位置
 	stackTopBiTree=-1;                   //初始化栈顶
 	stackTopSign=-1;
 	pushC('\0');                         //把空字符压入堆栈
 	while(*(exp+i)!='\0'||stackC[stackTopSign]!='\0') {   //当都为结束符号时
   		if((*(exp+i)<'0'||*(exp+i)>'9')&&(*(exp+i)!='.')){
  			 position2=i;                 //新的符号的位置
   			if(haveNum==1) {              //出现了数字开关,需要提取数字
   		    		BiTree nodeNum =(BiTree)malloc(sizeof(BiTree));
    				nodeNum->flag=1;
    				nodeNum->lchild=NULL;
    				nodeNum->rchild=NULL;
    				nodeNum->number=reap(exp,position1,position2);
    				pushB(nodeNum);
   				 haveNum=0;
   			}
   			switch(Precede(stackC[stackTopSign],*(exp+i))) { //比较
   			case '<':
    				pushC(*(exp+i));           //栈顶优先小,压堆栈
    				position1=position2;       //更新符号位置
    				i++;                       //表达式后移
    				break;
   			case '=':
    				popC();                    //脱括号
    				position1=position2;
    				i++;
    				break;
   			case '>':
   				sign=popC();               //符号和数出栈进行计算
    				BiTree t1,t2;
    				t2=popB();
   				 t1=popB();
   			 	pushB(CreatTreeNode(t1,sign,t2));
   				 break;
   			default: 
    				printf("errorout!");        //出错保护
    			break;
   			}
  		}else	{
  			 haveNum=1;
   			i++;
  		}
 	}
 	L=popB();
}
BiTree CalculateTree(BiTree tree)
{
         float leftValue,rightValue;
 	BiTree temp1,temp2;
 	if(tree->lchild->flag==2) { //左边结点是符号,继续算
 		temp1=CalculateTree(tree->lchild);
  		leftValue=temp1->number;
 		// free(temp1);
 	}else{                       //左边结点已经是数字了
 		 leftValue=tree->lchild->number;
         }
 	if(tree->rchild->flag==2){
  		temp2=CalculateTree(tree->rchild);
 	 	rightValue=temp2->number;
  		//free(temp2);
 	}else{
  		rightValue=tree->rchild->number;
         }
 	BiTree newNode=(BiTree)malloc(sizeof(BiTree));
 	newNode->flag=1;         //把算好后的结果组成新的数字结点返回
 	newNode->lchild=NULL;
 	newNode->rchild=NULL;
 	switch(tree->sign)
 	{
 	case '+': newNode->number=leftValue+rightValue;
    		break;
 	case '-': newNode->number=leftValue-rightValue;
    		break;
 	case '*': newNode->number=leftValue*rightValue;
   		break;
 	case '/': newNode->number=leftValue/rightValue;
    		break;
 	}
 	return newNode; 
}
void PrePrintTree(BiTree node)   //先序输出
{
      if(node->flag==2) printf("%c  ",node->sign);
      else printf("%f ",node->number);
      if((node->lchild))   PrePrintTree(node->lchild);
      if((node->rchild))   PrePrintTree(node->rchild);
}
void MidPrintTree(BiTree node)    //中序输出
{
      if((node->lchild))   MidPrintTree(node->lchild);
      if(node->flag==2) printf("%c  ",node->sign);
      else printf("%f ",node->number);
      if((node->rchild))   MidPrintTree(node->rchild);
}
void FolPrintTree(BiTree node)   //后序输出
{
      if((node->lchild))   FolPrintTree(node->lchild);
      if((node->rchild))   FolPrintTree(node->rchild);
      if(node->flag==2) printf("%c  ",node->sign);
      else printf("%f ",node->number);
}
void DeleteTree(BiTree node)
{
     if(!node)
        return ;
     if((node->lchild==NULL)&&(node->lchild==NULL)){
  		free(node);
  		return;
     }
     if(node->lchild) DeleteTree(node->lchild);
     if(node->rchild) DeleteTree(node->rchild);
}
void TablePrintTree(BiTree node,int tt)   //广义表输出
{
     int t=0,tSign=0;     //t是右括号开关,tt和tSign都是,开关
      if(node->flag==2)  {
          printf("%c(",node->sign);   //输出符号
            if(tt) tSign=1;            //如果符号结点也是左结点,后面括号后面也要加一个标点
      } else {
          printf("%f ",node->number);
  	 if(tt) printf(", ");           //如果是左结点输出点号
  	 t=1;
     }
     if((node->lchild))   TablePrintTree(node->lchild,1);
     if((node->rchild))   TablePrintTree(node->rchild,0);
     if(t==0) printf(")");          //如果是符号的循环就输出右括号
      if(tSign) printf(", ");
}
void main()
{
    BiTree L;
    InitExpTree(L);
    printf("前缀式输出:");
    PrePrintTree(L);
    printf("\n中缀式输出:");
    MidPrintTree(L);
    printf("\n后缀式输出:");
    FolPrintTree(L);
    printf("\n层次输出:");
    ccPrintTree(L);
    printf("\n值为:%f",CalculateTree(L)->number);
    printf("\n广义表为:");
    TablePrintTree(L,0);
 }




 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值