# 数据结构二叉树的基本操作c语言版二叉链表

数据结构二叉树的基本操作c语言版二叉链表


```java
 #include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#define   MAXSIZE 100

//定义操作符栈 (链式存储)
 typedef struct OptrNode
 {  char  optr;//节点数据域,存放操作符
     int  test;
    struct  OptrNode *next;//指针域 
 }OptrNode,*OpStackLink;



//定义二叉树链表
typedef struct BiTNode{
	char    optr;//数据域,如果是分支结点存运算符,如果是叶子结点存运算数
	float   data;//运算数
	int     flag;//标志位
	 
   struct  BiTNode  *lchild,*rchild;//左右孩子指针 
}BiTNode,*BiTree; 

 typedef struct BiTreeLink
 {
	 BiTree  Tree;
	 int  count;
  } BiTreeNode,*BiTreeLink;
  
//定义树根结点栈(链式存储)
 typedef struct ExptNode
 {    BiTNode *BiRoot;
	  struct ExptNode *next;  //指针域 
 }ExptNode,*BiRootStackLink;


//初始化操作符栈 
void InitOptrStack(OpStackLink *optrLink)
{
	
	  *optrLink=NULL;//初始化为空栈 
}

//初始化二叉树根结点栈 
void InitExptStack(BiRootStackLink *exptLink)
{
	  *exptLink = NULL;//初始化为空栈 
}
//创建只有根结点的二叉树链表
void CreatBiTreeList(BiTree *biTree,char optr,float data,int flag)
{

	  	//结点赋值
		  (*biTree)->optr=optr ;
		  (*biTree)->data= data ;
          (*biTree)->flag= flag ;
	      (*biTree)->lchild=NULL;   // 左子树为空 
	      (*biTree)->rchild=NULL;    //右子树为空 
		   printf("新创建的树:%f\n",(*biTree)->data);

	   
 }
 //为二叉树添加左右子树(多态应用) 
 void creatBiTreeList(BiTree *biTree,BiTree lchild,BiTree rchild,char optr,float data,int flag)
 {

	    (*biTree)->optr=optr ;
       (*biTree)->data= data ;
       (*biTree)->flag= flag ;
		(*biTree)->lchild = lchild;
		(*biTree)->rchild = rchild; 
	
		

 }
  /*栈的相关操作函数=================================================================*/
  
  //运算符栈入栈操作 
  void PushOpStack(OpStackLink *optrStack,char data)
  {
     
	 //分配结点空间
	 OpStackLink p = (OptrNode*)malloc(sizeof(OptrNode)); 
	 if(p)//如果分配成功
	 {
		  p->test=100;
	 	//strcmp(p->optr,data);
	 	p->optr=data;
	 	p->next = *optrStack;  //将新结点插入栈顶 
		*optrStack=p; //修改栈顶指针为p
		
	  } 
	 
	  
  }
  //二叉树根结点栈入栈操作 
  void PushBiRootStack(BiRootStackLink *exptStack,BiTree biTree)
  {
     
	 //分配结点空间
	 BiRootStackLink p = (BiRootStackLink)malloc(sizeof(ExptNode)); 
	 if(p)//如果分配成功
	 {
	 	//printf("当前入栈的树根原来是:%s\n",biTree->data); 
	    p->BiRoot=biTree; //将树的根结点赋值给新结点 
 	    p->next=*exptStack;//将新结点插入栈顶
	 	//printf("当前入栈的树根是:%s\n",p->BiRoot->data); 
		*exptStack=p; //修改栈顶指针为p
		 
	  } 
	 
	  
  }
  //算符栈出栈操作 
  char PopOpStack(OpStackLink *optrStack,char data)
  {
	 //判断栈是否为空
	 char ch;
	 if(*optrStack!=NULL) 
	 {
	     data = (*optrStack)->optr;    //取栈顶元素 
	     ch = (*optrStack)->optr;
	     //printf("%c",data);
	 	//用结点p暂存栈顶结点
		 OpStackLink p = (OpStackLink)malloc(sizeof(OptrNode));
		 p = *optrStack;
		 *optrStack= (*optrStack)->next;//修改栈顶指针
		 free(p) ;//释放原栈顶元素空间 
		 
	 }
	 return ch;
  }
   //二叉树根结点栈出栈操作 
  void PopBiRootStack(BiRootStackLink *exptStack,BiTree *biTree)
  {
  	//判断栈是否为空
	  if(*exptStack!=NULL)
	  {    *biTree = (*exptStack)->BiRoot;
	       BiRootStackLink  p = (BiRootStackLink)malloc(sizeof(ExptNode));
	       p =  *exptStack;
		   *exptStack=(*exptStack)->next;
		   //
		   printf("222当前弹出的树根是:%c\n",(*biTree)->optr);
		   printf("222当前弹出的树根是:%f\n",(*biTree)->data);
		   free(p); 
	      
  	   } 
  }
  //如果操作符栈和树根栈不为空,则弹出组合成最终的二叉树
  void GetBiTree(BiTree *b,OpStackLink *p,BiRootStackLink *s)
  {   	 
         int i=0;
		 while((*p)->optr!='#')                                                                 
		 {
		 	printf("OPTR");
		 	
		 	char data;
		 	BiTree rchild=(BiTree)malloc(sizeof(BiTNode)) ;   
            BiTree lchild=(BiTree)malloc(sizeof(BiTNode)) ;   
		    data =	PopOpStack(p,data) ;
			 
		    PopBiRootStack(s,&rchild);   //第一次弹出的为右子树 
		    PopBiRootStack(s,&lchild);     //第二次弹出的为左子树 
		    i++;
		
		    BiTree  biTree_Temp  = (BiTree)malloc(sizeof(BiTNode)) ;
		    creatBiTreeList(&biTree_Temp,lchild,rchild,data,0,0) ;
		    *b=  biTree_Temp;
		   
			 
		 }  
  } 
  //遍历二叉树得到运算结果
   void TravelCompute(BiTree  b,float *tValue)
   {   
    float lvalue=0.0,rvalue=0.0;
   
   	  if(b!=NULL)                  
   	  {
		 if(b->lchild==NULL&&b->rchild==NULL)
		 {
			  *tValue=b->data;
		 }
		 else
		 {
		 	TravelCompute(b->lchild,&lvalue) ;
		 	TravelCompute(b->rchild,&rvalue) ;
		 	*tValue=lvalue+rvalue;
		 }
   	  	
	 }
   }
  //输入算术表达式 
  void InputExpression(BiTree *biTree)
  {
	 char  express[MAXSIZE],temp[MAXSIZE] ; //辅助字符数组,用来存储连续的数字 
	 BiRootStackLink  rootStack= (BiRootStackLink)malloc(sizeof(ExptNode)) ;//存树根结点的栈 
	 OpStackLink  opStack = (OpStackLink)malloc(sizeof(OptrNode)) ;//存放运算符的栈 
	 InitOptrStack(&opStack);
	 InitExptStack(&rootStack);
	 gets(express) ;
	  //先压入'#'作为出栈完成标志
     PushOpStack(&opStack,'#');
	 int i;
	 for(i=0;express[i]!='\0';i++) 
	 {    
	 	
	 	memset(temp,'\0',sizeof(temp)); //将上一次匹配的数字清空,重新匹配 
	 	//如果是数字
	 	if(express[i]>='0'&&express[i]<='9')
	 	{
	 		//构建只有根结点的树,并压入expt栈中
	 		 BiTree  biTree_Temp  = (BiTree)malloc(sizeof(BiTNode)) ;
	 		 //biTree_Temp = NULL;
	 		 //将连续的数字存放在temp中
			  temp[0]=express[i];
			  //继续判断是否为数字
			  int j,ti=1;
			  
			  for(j=i+1;express[j]!='\0';j++)
			  {
			  	if(express[j]>='0'&&express[j]<='9')
			  	{
			  		temp[ti]=express[j];//存入temp
					ti++; 
				  }
				  else
				  {
				  
				  	break;//如果为非数字退出循环 
				  }
				  i=j;//从j位置开始匹配 
				  
			   } 
			   float num=atof(temp) ;
			     
			   CreatBiTreeList(&biTree_Temp,'#',num,1); 
			   printf("当前构造的树的根为:%f\n",biTree_Temp->data);
			 PushBiRootStack(&rootStack,biTree_Temp); 
			 
			 
		
		 }
		 //如果式运算符 ,根据运算符优先级进行操作 
	 	 else  if(express[i]=='+')
		 {      
			 
			switch(express[i])
		    {
				  
				 //与栈顶元素进行比较 
				case '+'  :
					if(opStack->optr!='+'&&opStack->optr!='-'&&opStack->optr!='*'&&opStack->optr!='/')    //优先级高于栈顶元素,入栈 
					{
						 
						 PushOpStack(&opStack,'+');
						 
					}
					else
					{
						//如果优先级低于栈顶元素,弹出栈顶元素 ,同时需从二叉树树根栈弹出两个结点,用于构造新的二叉树
						char data; 
					    data =	PopOpStack(&opStack,data) ;
					    
						printf("当前弹出的是:%c\n",data);
						//printf("当前弹出的是:%s\n",dataStr[0]);
						//弹出树根栈的顶部两个元素
						BiTree lchild=(BiTree)malloc(sizeof(BiTNode)) ;
					    BiTree rchild=(BiTree)malloc(sizeof(BiTNode)) ;
					   
					    BiTree  biTree_Temp1  = (BiTree)malloc(sizeof(BiTNode)) ;
	 		           
					    PopBiRootStack(&rootStack,&rchild) ; //第一次弹出的为右子树 
					    PopBiRootStack(&rootStack,&lchild) ; //第二次弹出的为左子树
					    printf("弹出的左子树为:%f",lchild->data) ;
					    printf("弹出的右子树为:%f",rchild->data) ;
						//构造新树
						creatBiTreeList(&biTree_Temp1,lchild,rchild,data,0,0) ;
							
						//将新树根结点压入expt栈
						PushBiRootStack(&rootStack,biTree_Temp1); 
						//将'+'入OPTR栈
						 PushOpStack(&opStack,'+'); 
					}
					break;
					
			}
		 
			 
		 }	
	 }
	 
	 
	 GetBiTree(biTree,&opStack,&rootStack); 
	 
	
	 
  }
  
int  main()
{
	
    BiTree  biTree;
    biTree = (BiTree)malloc(sizeof(BiTNode));
    //CreatBiTreeList(biTree,"+"); //传入字符串
     InputExpression(&biTree);
	  printf("二叉树根的值为:%c\n",biTree->optr);
	  printf("二叉树左子树的值为:%c\n",biTree->lchild->optr);
	   printf("二叉树右子树的值为:%f\n",biTree->rchild->data);
	   printf("二叉树右子树的值为:%c\n",biTree->rchild->optr);
	   float sum=0.0;
	   TravelCompute(biTree,&sum);
	   printf("计算结果为:%.2f",sum);
     return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值