树的相关概念

树的定义

由零个或多个节点组成的有限集合,其中有且仅有一个节点,成为树根(root),其余的节点为m个互不相交的有限集合,每个集合本事又是一棵树,称为这棵树的子树。

树的特点

1.是非线性结构,除了根之外,所有节点都有一个直接前驱,但是可能有多个直接后继;

2.树的定义具有递归性,树中还有树

3.树可以为空,即树中节点的个数为0。

树的术语

树根:即树的根节点,特点是没有前驱。

叶子:即终端节点,没有后继。

双亲:即某个节点的直接前驱。

孩子:即某个节点的直接后继。

兄弟:同一个双亲下的节点互称为兄弟。

堂兄弟:即双亲为兄弟的节点,互称为堂兄弟。

节点的度:节点下挂接的子树的个数。

树的度:树中所有节点度的最大值。

节点的层数:从根到该节点的层数,默认树根是第一层。

树的深度(高度):树中所有节点层数最大值。

二叉树

概念:由0或多个节点组成的有限集合,其中由一个根节点以 及2个互不相交的有限集合,左子树和右子树,也就是度为2的树。

二叉树的特点

1.每个节点最多有两个子树,不存在度大于2的节点;

2.二叉树的左右子树次序不能颠倒。

二叉树的性质

1.在二叉树的第i层上,最多有2^{i}-1个结点

遍历二叉树

1.先构造一个结点类

#include<iostream>
using namespace std;
class biTreeNode//节点类
{
public:
	int val;
	biTreeNode* left;
	biTreeNode* right;

	biTreeNode()//构造
	{
		val = NULL;
		left = nullptr;
		right = nullptr;
	}
	biTreeNode(int value)//有参构造
	{
		val = value;
		left = nullptr;
		right = nullptr;
	}
};

2.创建一颗树

biTreeNode* craetebiTree()//创建树
{
	biTreeNode* a = new biTreeNode(1);
	biTreeNode* b = new biTreeNode(2);
	biTreeNode* c = new biTreeNode(3);
	biTreeNode* d = new biTreeNode(4);
	biTreeNode* e = new biTreeNode(5);
	biTreeNode* f = new biTreeNode(6);
	biTreeNode* g = new biTreeNode(7);
	biTreeNode* h = new biTreeNode(8);
	biTreeNode* i = new biTreeNode(9);
	biTreeNode* j = new biTreeNode(10);
	a->left = b;
	a->right = c;
	b->left = d;
	b->right = e;
	c->left = f;
	c->right = g;
	d->left = h;
	d->right = i;
	e->left = j;
	return a;//此时返回的a就是指向树根的指针,所以后续遍历的时候,调用这个函数,返回的就是树根的指针,使用root结点接收这个指针
}

3.遍历

遍历分为前序遍历,中序遍历,后序遍历。

先序遍历:先遍历根结点,再遍历左子树,最后遍历右子树;

中序遍历:先遍历左子树,再遍历根结点。最后遍历右子树;

后序遍历:先遍历左子树,再遍历右子树,最后遍历根结点。

其中,这些遍历都是通过函数的递归实现的,遍历主要以根结点来命名具体遍历方式的,比如根结点在中间,就是中序遍历。

求叶子个数的函数思路:先判断是否为空树,如果不为空,判断结点的左子树和右子树是否都为空,如果都为空,则表示这个结点是叶子,左子树的叶子结点个数加右子树的叶子结点个数就是总叶子个数。

求树高度的函数思路:通过递归将左子树的高度和右子树的高度求出,返回较大值,然后加上根结点,就是树的总高度。

void preOrder(biTreeNode* root)//先序遍历
{
	if (root == nullptr)
	{
		return;
	}
	cout << root->val << " ";
	preOrder(root->left);
	preOrder(root->right);
}

void inOrder(biTreeNode* root)//中序遍历
{
	if (root == nullptr)
	{
		return;
	}
	else
	{
		inOrder(root->left);
		cout << root->val << " ";
		inOrder(root->right);
	}
}

void popOrder(biTreeNode* root)//后序遍历
{
	if (root == nullptr)
	{
		return;
	}
	else
	{
		popOrder(root->left);
		popOrder(root->right);
		cout << root->val << " ";
	}
}
int calcaulateLeafNum(biTreeNode* root)//叶子个数
{
	if (root == nullptr)
	{
		return NULL;
	}
	if (root->left == nullptr && root->right == nullptr)
	{
		calcaulateLeafNum(root->left);
		calcaulateLeafNum(root->right);
		return 1;
	}
	return  calcaulateLeafNum(root->left) + calcaulateLeafNum(root->right);
}

void  calcaulateLeafNum2(biTreeNode* root, int* a)//无返回值做法
{
	if (root == nullptr)
	{
		return;
	}
	
	if (root->left == nullptr && root->right == nullptr)
	{
		(*a)++;
	}
	calcaulateLeafNum2(root->left,a);
	calcaulateLeafNum2(root->right,a);
}

int binaryTree_height(biTreeNode* root)//树的高度,有返回值做法
{
	if (root == nullptr)
	{
		return 0;
	}
	else
	{
		int a = binaryTree_height(root->left);//左子树的高度
		int b = binaryTree_height(root->right);//右子树的高度
		return max(a, b)+1;//计算左右子树高度的最大值,+1的原因是,左子树为3,右子树为2,需要加上头结点。
	}
	
}

int main()
{
	biTreeNode* root = craetebiTree();
	preOrder(root);
	cout << endl;
	inOrder(root);
	cout << endl;
	popOrder(root);
	cout << endl;
	cout<<calcaulateLeafNum(root)<<endl;
	cout << binaryTree_height(root) << endl;
	int a = 0;
	calcaulateLeafNum2(root, &a);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值