二叉树的基本操作

简介:树形结构是一种典型的非线性结构,它能够反映元素之间的层次关系和分支关系,树形结构在现实生活中应用很多,比如家族的族谱关系,公司的组织关系等等。

二叉树的基本操作是本文的主要内容。

掌握:学习二叉树结构,首先要掌握二叉树的性质、二叉树的顺序存储结构、二叉树的链式存储结构、二叉树的遍历方式等基本定义。

二叉树可以为空树,也可以为一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。是一种有序树(左右不可颠倒),可以缺少其中一棵或两棵子树。

二叉树的链式存储结构定义:

typedef struct BiTNode {
//数据域
	TElemType data;
//指向左右孩子指针
	struct BiTNode *LChild, *RChild;
}BiTNode, *BiTree;


元素输入:

void inputTElem(TElemType &e){
	scanf("%c", &e);
}


判断元素输入中代表空树的特殊值:

status isEmptyElem(TElemType e){
	if (e == '#') return OK;
	else return ERROR;
}


创建二叉树:

void createBiTree(BiTree &T) {
//按照【先序次序】输入二叉树中结点的值创建二叉树T
	TElemType e;
//输入
	inputTElem(e);
//判空,若为空建立一个空树
	if (isEmptyElem(e)) T = NULL;
	else {
//申请一个节点空间
		T = (BiTree)malloc(sizeof(BiTree));
//生成根节点
		T->data = e;
//先序创建左子树
		createBiTree(T->LChild);
//先序创建右子树
		createBiTree(T->RChild);
	}
}

先序遍历二叉树:

void PreOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	if (T){
//先访问根节点
		visit(T->data);
//遍历左子树
		PreOrderTraverse(T->LChild, visit);
//遍历右子树
		PreOrderTraverse(T->RChild, visit);
	}
}

中序遍历二叉树:

void InOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	if (T){
		InOrderTraverse(T->LChild, visit);
//中间访问节点
		visit(T->data);
		InOrderTraverse(T->RChild, visit);
	}
}

后序遍历二叉树:

void PostOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	//后序遍历二叉树T的递归算法
	if (T){
		PostOrderTraverse(T->LChild, visit);
		PostOrderTraverse(T->RChild, visit);
//最后访问节点
		visit(T->data);
	}
}

统计二叉树中叶子节点的个数:

int countLeaf(BiTree T){
//定义两个整形变量分别记录左、右子树的叶子节点数
	int countLeft, countRight;
//如果此时T为空树,直接返回0
	if (!T) return 0;
//判断此时T是否没有孩子,没有的话直接返回本身1
	if (T->LChild == NULL&&T->RChild == NULL) return 1;
//经过两次if,确定有孩子,再次使用countLeaf()计算孩子的叶子节点数
	countLeft = countLeaf(T->LChild);
	countRight = countLeaf(T->RChild);
//直到全部计算完成返回总和的值
	return  countLeft + countRight;
}

求二叉树的深度:

int depthBiTree(BiTree T){
//和求叶子节点数是一个原理...分别记录深度
	int depthLeft, depthRight;
//如果此时T为空树,就不计算它的深度,返回0
	if (!T) return 0;
//只要T此时不是空树就继续使用这个函数往下找,判断T的孩子,孩子的孩子...总会到头...
	else {
		depthLeft = depthBiTree(T->LChild);
		depthRight = depthBiTree(T->RChild);
//看看哪个大就取哪个,加到最后就是深度了
		if (depthLeft >= depthRight) return depthLeft + 1;
		else return  depthRight + 1;
//返回的最后一个就是最终要求的深度
	}
}


代码:

#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#define ERROR 0
#define OK    1
typedef int status;

typedef struct BiTNode {
//数据域
	TElemType data;
//指向左右孩子指针
	struct BiTNode *LChild, *RChild;
}BiTNode, *BiTree;

void inputTElem(TElemType &e){
	scanf("%c", &e);
}

status isEmptyElem(TElemType e){
	if (e == '#') return OK;
	else return ERROR;
}


void createBiTree(BiTree &T) {
//按照【先序次序】输入二叉树中结点的值创建二叉树T
	TElemType e;
//输入
	inputTElem(e);
//判空,若为空建立一个空树
	if (isEmptyElem(e)) T = NULL;
	else {
//申请一个节点空间
		T = (BiTree)malloc(sizeof(BiTree));
//生成根节点
		T->data = e;
//先序创建左子树
		createBiTree(T->LChild);
//先序创建右子树
		createBiTree(T->RChild);
	}
}

void PreOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	if (T){
//先访问根节点
		visit(T->data);
//遍历左子树
		PreOrderTraverse(T->LChild, visit);
//遍历右子树
		PreOrderTraverse(T->RChild, visit);
	}
}

void InOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	if (T){
		InOrderTraverse(T->LChild, visit);
//中间访问节点
		visit(T->data);
		InOrderTraverse(T->RChild, visit);
	}
}

void PostOrderTraverse(BiTree T, void(*visit)(TElemType &e)) {
	//后序遍历二叉树T的递归算法
	if (T){
		PostOrderTraverse(T->LChild, visit);
		PostOrderTraverse(T->RChild, visit);
//最后访问节点
		visit(T->data);
	}
}

int countLeaf(BiTree T){
//定义两个整形变量分别记录左、右子树的叶子节点数
	int countLeft, countRight;
//如果此时T为空树,直接返回0
	if (!T) return 0;
//判断此时T是否没有孩子,没有的话直接返回本身1
	if (T->LChild == NULL&&T->RChild == NULL) return 1;
//经过两次if,确定有孩子,再次使用countLeaf()计算孩子的叶子节点数
	countLeft = countLeaf(T->LChild);
	countRight = countLeaf(T->RChild);
//直到全部计算完成返回总和的值
	return  countLeft + countRight;
}

int depthBiTree(BiTree T){
//和求叶子节点数是一个原理...分别记录深度
	int depthLeft, depthRight;
//如果此时T为空树,就不计算它的深度,返回0
	if (!T) return 0;
//只要T此时不是空树就继续使用这个函数往下找,判断T的孩子,孩子的孩子...总会到头...
	else {
		depthLeft = depthBiTree(T->LChild);
		depthRight = depthBiTree(T->RChild);
//看看哪个大就取哪个,加到最后就是深度了
		if (depthLeft >= depthRight) return depthLeft + 1;
		else return  depthRight + 1;
//返回的最后一个就是最终要求的深度
	}
}

int main(){
//建立空树
	BiTree T;
	printf("输入字符序列创建二叉树T:\n");
//创建树T
	createBiTree(T);
	printf("先序遍历:");
	PreOrderTraverse(T, visit);
	printf("\n中序遍历:");
	InOrderTraverse(T, visit);
	printf("\n后序遍历:");
	PostOrderTraverse(T, visit);
	printf("\n叶子节点数:%d\n", countLeaf(T));
	printf("深度:%d\n", depthBiTree(T));
	system("pause");
	return 0;
}

测试二叉树:


测试输入树:ABD#G###CE##F##

测试结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值