算法设计学习:二叉树算法

(1)题目:表达式(a-(b+c))*(d/e)存储在二叉树链表中,结点为char型,编写程序计算出该表达式的值(表达式中操作数为整数)

分析:后序遍历,先求左子树表达式的值,再求右子树表达式的值,然后就求两个结果的值。

代码:

typedef struct  BTNode  
{  
	char  data;     //默认为int型,或者写成 ElementType   element  
	struct  BTNode *lchild;  
	struct  BTNode *rchild;  
} BTNode; 	//二叉树结点定义

int compute(BTNode *p)
{
	int A, B;
	if ( NULL != p )
	{
		if (NULL != p->lchild && NULL != p->rchild )  //后序遍历
		{
			A = compute(p->lchild);
			B = compute(p->rchild);
			return operation(A,B,p->data);
		}
		else
		{
			return (p->data - '\0');	//左右子树为空,则为数值,直接返回
		}
	}
	else
	{
		return 0;	  //空树,表达式的值为0
	}
}

int operation(int a, int b, char c)
{
	int temp = 0;
	switch( c )
	{
	case '+': 
		temp = a + b; 
		break;
	case '-': 
		temp = a - b; 
		break;
	case '*': 
		temp = a * b; 
		break;
	case '/': 
		temp = a / b; 
		break;
	case '%': 
		temp = a % b; 
		break;
	default:
		break;	 //不够严谨,没有处理特殊情况
	}
	return temp;
}

(2)题目:设计算法求二叉树的深度,二叉树为二叉链表存储。

分析:若左子树深度为LD,右子树深度为RD,则整个树的深度为max{LD, RD} + 1      ,后序遍历

代码:

typedef struct  BTNode  
{  
	char  data;     //默认为int型,或者写成 ElementType   element  
	struct  BTNode *lchild;  
	struct  BTNode *rchild;  
} BTNode; 	//二叉树结点定义

int getDepth(BTNode *p)
{
	int LD, RD;
	if (NULL == p)
	{
		return 0;   //空树,返回0
	}
	else
	{
		LD = getDepth(p->lchild);    //左子树深度
		RD = getDepth(p->rchild);    //右子树深度

		return	(LD > RD ? LD : RD) + 1 ;   //整棵树的深度
	}
}

(3)题目:二叉链表存储的二叉树中,查找data为key的结点是否存在(找到任何一个满足要求的结点即可),若存在,将q指向该结点,否则q赋值为NULL

分析:二叉树遍历,逐一判断。

代码:

typedef struct  BTNode  
{  
	char  data;     //默认为int型,或者写成 ElementType   element  
	struct  BTNode *lchild;  
	struct  BTNode *rchild;  
} BTNode; 	//二叉树结点定义
void search( BTNode *p, BTNode *&q, char key)	 //将参数q定义为引用指针型,因为q要改变
{
	if ( NULL != p )   //
	{
		if ( key == p->data) //如果是字符串数据,则使用strcmp()函数
		{
			q = p  ;   //若是找到,则赋值
		}
		else
		{
			search(p->lchild, q, key);	 //到左子树中查找
			search(p->rchild, q, key);	 //到右子树中查找

			/*********************************************/
			/* 改进建议如下:如果在左子树中没找到,再到右子树中查找*/
// 			search(p->lchild, q, key);	 //到左子树中查找
// 			if ( NULL == q )
// 			{
// 				search(p->rchild, q, key);	 //到右子树中查找
// 			}
			/********************************************/
		}
	}
	/* 如果是空树,则什么也不用做,保持 q = NULL  */
}

补充:在二叉树的前、中、后三种遍历中的   前和中,中和后   两对遍历序列都可以唯一确定这棵二叉树,根据   前和后,则不能确定。


题目(4):二叉树链表存储,编写算法,输出先序遍历中,第k个结点的值。(k不大于总结点数,data为char型)

分析:添加判断代码,确定指针p第一次经过该节点时的操作

代码:

int ncount = 0;  //定义全局变量nCount,将结点计数初值设为0
void trave(BTNode *p, int k)
{
	if ( NULL != p )
	{
		++ ncount ;
		if ( k == ncount )	   //当第一次来到这个结点的时候,判断这个结点是否是先序序列中的第k个结点
		{
			cout << p->data << endl;	 //如果是,则输出;并且无需遍历,使用return直接返回
			return;					  
		}
		trave(p->lchild, k);
		trave(p->rchild, k);
	}
}

//改为中序,如下
void trave(BTNode *p, int k)
{
	if ( NULL != p )
	{
		trave(p->lchild, k);

		++ ncount ;
		if ( k == ncount )	   //当第一次来到这个结点的时候,判断这个结点是否是中序序列中的第k个结点
		{
			cout << p->data << endl;	 //如果是,则输出;并且无需遍历,使用return直接返回
			return;					  
		}
	
		trave(p->rchild, k);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值