树与二叉树的基本操作

//二叉树的链式存储结构:
typedef int ElemType;
typedef struct BiTNode{
	ElemType data;
	struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree; 

1、统计二叉树中度为0的结点个数

//统计二叉树中度为0的结点个数 
int NodeDegree_0(BiTree bt){
	//如果根结点不为空 
	if(bt != NULL){
		//如果根结点左右子树均为空,则度为1的结点数为1 
		if(bt->lchild == NULL && bt->rchild == NULL) 
		return 1;
		//否则返回根结点的左右子树的度为1的结点数之和 
		else return NodeDegree_0(bt->lchild) + NodeDegree_0(bt->rchild);
	}
	else return 0;
}

2、统计二叉树中度为1的结点个数

//统计二叉树中度为1的结点个数 
int NodeDegree_1(BiTree bt){
	//如果根结点不为空 
	if(bt != NULL){
		//如果根结点左、右子树其中有一个为空,则返回根结点的左右子树的度为1的结点数之和+1 
		if((bt->lchild != NULL && bt->rchild == NULL) || (bt->rchild != NULL && bt->lchild == NULL)) 
		return NodeDegree_1(bt->lchild) + NodeDegree_1(bt->rchild) + 1;
	    //否则返回根结点的左右子树的度为1的结点数之和 
		else return NodeDegree_1(bt->lchild) + NodeDegree_1(bt->rchild);
	}
	else return 0;
}

3、统计二叉树中度为2的结点个数

//统计二叉树中度为2的结点个数 
int NodeDegree_2(BiTree bt){
	//如果根结点不为空 
	if(bt != NULL){
		//如果根结点左、右子树均不为空 
		if(bt->lchild != NULL && bt->rchild != NULL) 
		//则返回根结点的左右子树的度为2的结点数之和+1 
		return NodeDegree_2(bt->lchild) + NodeDegree_2(bt->rchild) + 1;
		//否则返回根结点的左右子树的度为2的结点数之和 
		else return NodeDegree_2(bt->lchild) + NodeDegree_2(bt->rchild);
	}
	else return 0;
}

4、统计二叉树的高度

//统计二叉树的高度
int getHeight(BiTree bt){
	//若根节点为空,则高度为0 
	if(bt == NULL) return 0;
	//获取根节点左子树高度 
	int hl = getHeight(bt->lchild);
	//获取根节点右子树高度 
	int hr = getHeight(bt->rchild);
	//取左、右子树高度较大者结果+1 
	return (hl > hr ? hl : hr) + 1;
}

5、统计二叉树的宽度

//统计二叉树的宽度
int getWidth(BiTree bt){
	//利用广度优先遍历的思想,定义一个辅助队列 
	queue<BiTree> q;
	//记录当前层次的宽度 
	int width = 0;
	//记录最大的宽度 
	int maxWidth = 0;
	//队列初始化,根结点入队 
	q.push(bt);
	//定义一个工作指针 
	BiTNode *p = NULL;
	while(!q.empty()){
		//记录当前层次的宽度 
		width = q.size();
		for(int i = 0; i < width; i++){
			//获取当前队头元素 
			p = q.front();
			//出队 
			q.pop();
			//左孩子不为空,则左孩子入队 
			if(p->lchild != NULL){
				q.push(p->lchild);
			}
			//右孩子不为空,则右孩子入队 
			if(p->rchild != NULL){
				q.push(p->rchild);
			}
		}
		//更新当前宽度 
		if(width > maxWidth)
		maxWidth = width;
	}
	return maxWidth;
} 

6、从二叉树中删除所有叶结点

//删除所有叶结点
void DelLeafNode(BiTree bt){
	BiTNode *p = bt;
	//如果只有根节点或无根节点 
	if((p->lchild == NULL && p->rchild == NULL) || p == NULL){
		free(p);
		return;
	}
	else if(p->lchild->lchild == NULL && p->lchild->rchild == NULL){
		free(p->lchild);
		p->lchild = NULL;
	}
	else if(p->rchild->lchild == NULL && p->rchild->rchild == NULL){
		free(p->rchild);
		p->rchild = NULL;
	}
	DelLeafNode(bt->lchild);
	DelLeafNode(bt->rchild);
} 

7、计算指定结点*p所在的层次

//求指定结点*p所在的层次 
int GetLevel(BiTree bt,BiTNode *p){
	//如果根节点为空,则所在层次为0 
	if(bt == NULL) return 0;
	//如果根节点即为p,则所在层次为1 
	if(bt == p) return 1;
	//获取结点p在左子树中的高度 
	int depl = GetLevel(bt->lchild, p);
	//获取结点p在右子树中的高度 
	int depr = GetLevel(bt->rchild, p);
	//若depl和depr中有一个不为0,则取其中的最大值+1即为p所在层次 
	if(depl || depr){
		if(depl > depr) return depl + 1;
		else return depr + 1;
	}
	return 0;
}

8、计算二叉树各结点中最大元素的值。

//计算各结点中最大元素的值
int GetMaxNode(BiTree bt){
	//如果根结点为空,则最大元素之为0 
	if(bt == NULL) return 0;
	//获取根结点左子树的最大元素值 
	int maxl = GetMaxNode(bt->lchild);
	//获取根结点右子树的最大元素值 
	int maxr = GetMaxNode(bt->rchild);
	//取左、右子树最大元素值中的最大值 
	int maxlr = maxl > maxr ? maxl : maxr;
	//取左、右子树最大元素值中的最大值与根结点中的最大值 
	int maxNode = maxlr > bt->data ? maxlr : bt->data;
	return maxNode;
	}

9、交换二叉树中每个结点的两个子女

//交换二叉树中每个结点的两个子女
void SwapNodeChild (BiTree bt){
	//如果左子树不为空,对左子树做递归操作 
	if(bt->lchild != NULL)
	SwapNodeChild(bt->lchild);
	//如果右子树不为空 ,对右子树做递归操作  
	if(bt->rchild != NULL)
	SwapNodeChild(bt->rchild);
	//对左、右孩子进行交换操作 
	BiTNode *p = bt->lchild;
	bt->lchild = bt->rchild;
	bt->rchild = p;
}

10、以先序次序输出一颗二叉树中所有结点的数据值及结点所在的层次。

//以先序次序输出一颗二叉树中所有结点的数据值及结点所在的层次
void PrintByPreOrder(BiTree bt,int level){
	//如果根不为空,利用先序遍历算法依次访问每个结点,并用level变量记录遍历的层次 
	if(bt != NULL){
		cout << level << ":" << bt->data << endl;
		PrintByPreOrder(bt->lchild,level);
		PrintByPreOrder(bt->rchild,level);
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值