树相关知识以及二叉树的介绍

<一>树的基本概念

在这里插入图片描述

1.节点的度:一个节点含有的子数的个数。如图:A的度为6
2.叶节点或终端节点:度为0的节点称为叶节点,如图,B,C,H,L等节点为叶节点
3.非终端节点或分支节点:度不为0的节点,如上图,D,E,F,G等节点为分支节点
4.双亲结点或父节点:若一个结点含有子节点,则这个节点称为其子节点的父节点,如上图,A是B的父节点
5.孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点,如上图,B是A的孩子节点
6.兄弟节点:具有相同父节点的节点互称为兄弟节点,如上图,B,C是兄弟节点
7.树的度:一棵树中,最大的节点的度称为树的度,如上图,树的度为6
8.节点的层次:从根开始定义起,根为第一层,根的子节点为第二层,以此类推
9.树的高度和深度:树中节点的最大层次,如上图:树的高度是4
10.堂兄弟节点:双亲在同一层的节点互为堂兄弟,如上图,H,I互为堂兄弟节点
11.节点的祖先:从根到该节点所经分支上的所有节点,如上图,A是所有节点的祖先
12.子孙:以某节点为根的子树中任一节点都称为该节点的子孙,如上图,所有节点都是A的子孙
13.森林:由m(m>0)棵互不相交的树的集合称为森林,并查集就是森林 注意:树形结构中,子树不能有交集,否则就不是树形结构,一棵N个结点的树有N-1条边

<一>二叉树的概念及结构

1.概念

一棵二叉树是结点的一个有限集合,该集合:
1.或者为空
2.由一个根节点加上两棵别称为左子树和右子树的二叉树组成

在这里插入图片描述

  • 从上图可以看出:
    1.二叉树不存在度大于2的结点
    2.二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树 注意:对于任意的二叉树都是由以下几种情况复合而成的:

在这里插入图片描述

2.特殊的二叉树

1.满二叉树:一个二叉树,如果每一层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k-1,则它就是满二叉树。

2.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引起的。对于深度为K的,有n个结点的为叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1到n的结点一一对应时称之为完全二叉树,要注意的是满二叉树是一种特殊的完全二叉树

在这里插入图片描述

3.二叉树的性质

1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多2^(i-1)个结点
2.若规定根节点的层数为1,则深度为h的为叉树的最大结点数时2^h-1
3.对任何一棵二叉树,如果度为0其叶结点个数为n0,度为2的分支结点个数为n2,则有n0 =n2+1
4.若规定根节点的层数为1,具有n个结点的满二叉树的深度,h = log2(n+1),(ps:log2(n+1)是log以2为底,n+1为对数)
5.下标计算父子间的关系:
在这里插入图片描述

4.二叉树的遍历

1.构建二叉树的结构体

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTDataType data;
}BTNode;

2.创建二叉树的结点

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	assert(node);
	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}

3.链接二叉树中每个结点

BTNode* CreatBinaryTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);

	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	//node3->right = node7;
	node2->right = node7;
	return node1;

}

4/先序/前序遍历

前序遍历顺序:根,左子树,右子树

//先序/前序遍历
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}
	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

5.中序遍历

中序遍历顺序:左子树,根,右子树

//中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	} 
	InOrder(root->left);
	printf("%d ", root->data);
	PreOrder(root->right);
}

6.后序遍历

后序遍历顺序:左子树,右子树,根

//后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

5.求二叉树的节点个数

//第一种
int count = 0;
void TreeSize(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	++count;
	TreeSize(root->left);
	TreeSize(root->right);

} 
//第二种
int TreeSize2(BTNode* root)
{
	return root == NULL ? 0 : TreeSize2(root->left) + TreeSize2(root->right) + 1;
}

6.求二叉树的叶子结点个数

int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

7.求第k层的结点个数

int TreeKLevel(BTNode* root,int k)
{
	assert(k >= 1);
	if (root == NULL)return 0;
	if (k == 1)return 1;
	return TreeKLevel(root->left, k - 1) + TreeKLevel(root->right, k - 1);
}

8.求二叉树的深度

//求二叉树的深度
int TreeDepth(BTNode* root)
{
	if (root == NULL)return 0;
	
	int leftDepth = TreeDepth(root->left);
	int rightDepth = TreeDepth(root->right);
	return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}

9.查找二叉树值为x的节点

//查找二叉树值为x的节点
BTNode* TreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)return NULL;
	if (root->data == x)return root;
	BTNode* left = TreeFind(root->left, x);
	BTNode* right = TreeFind(root->right, x);
	if (left)
		return left;
	if(right)
		return right;
	return NULL;
}

10.判断是不是单值二叉树

//判断是不是单值二叉树
bool isUnivalTree(BTNode* root)
{
	if (root == NULL)
		return true;
	if (root->left && root->left->data != root->data)
		return false;
	if (root->right && root->right->data != root->data)
		return false;
	return isUnivalTree(root->left) && isUnivalTree(root->right);
}

11.判断是不是对称二叉树

//判断是不是对称二叉树
bool isSymmertricSubTree(BTNode* Left, BTNode* Right)
{
	if (Left == NULL && Right == NULL)
		return true;
	if (Left == NULL || Right == NULL)
		return false;
	if (Left->data != Right->data)
		return false;
	return isSymmertricSubTree(Left->left, Right->right) && isSymmertricSubTree(Left->left, Right->right);
}

12.树的销毁

//树的销毁
void TreeDestroy(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	TreeDestroy(root->left);
	TreeDestroy(root->right);
	free(root);
}

13.二叉树的层序遍历

//二叉树的层序遍历
void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%d", front->data);
		QueuePop(&q);
		if (front->left)
		{
			QueuePush(&q, front->left);
		}
		if (front->right)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

14.判断是不是完全二叉树

//判断是不是完全二叉树
bool TreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
		{
			QueuePush(&q, front->left);
			QueuePush(&q, front->right);
		}
		else
		{
			break;
		}
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);
	return true;
}

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值