C:树和二叉树

目录

1、树的相关概念:

2、二叉树的概念: 

2.1、特殊的二叉树:

2.2、二叉树的性质:

2.3、二叉树的实现:

3、二叉树的遍历:

3.1、前序遍历:

3.2、中序遍历:

3.3、后序遍历:

3.4、层序遍历:


1、树的相关概念:

节点的度 :一个节点含有的子树的个数称为该节点的度; 如上图: A 的度为 6。
叶节点或终端节点 :度为 0 的节点称为叶节点; 如上图: B C H I... 等节点为叶节点。
非终端节点或分支节点 :度不为 0 的节点; 如上图: D E F G... 等节点为分支节点。
双亲节点或父节点 :若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图: A B 的父节点。
孩子节点或子节点 :一个节点含有的子树的根节点称为该节点的子节点; 如上图: B A 的孩子节点。
兄弟节点 :具有相同父节点的节点互称为兄弟节点; 如上图: B C 是兄弟节点。
树的度 :一棵树中,最大的节点的度称为树的度; 如上图:树的度为 6。
节点的层次 :从根开始定义起,根为第 1 层,根的子节点为第 2 层,以此类推。
树的高度或深度 :树中节点的最大层次; 如上图:树的高度为 4。
堂兄弟节点 :双亲在同一层的节点互为堂兄弟;如上图: H I 互为兄弟节点。
节点的祖先 :从根到该节点所经分支上的所有节点;如上图: A 是所有节点的祖先。
子孙 :以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是 A 的子孙。
森林 :由 m m>0 )棵互不相交的树的集合称为森林。

2、二叉树的概念: 

二叉树是一个节点的有限集合:1、为空;2、有一个根节点加上两颗分别成为左子树和右子树的二叉树组成;3、每个节点的度最多是2;二叉树有左右之分,次序不能颠倒,因此二叉树是是有序树。

2.1、特殊的二叉树:

1. 满二叉树 :一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K ,且结点总数是 2^k - 1,则它就是满二叉树。
2. 完全二叉树 :完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为 K 的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为 K 的满二叉树中编号从 1 n 的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

2.2、二叉树的性质

1. 若规定根节点的层数为 1 ,则一棵非空二叉树的 i 层上最多有2^{i - 1}个结点.
2. 若规定根节点的层数为 1 ,则 深度为 h 的二叉树的最大结点数是2^{h} - 1.
3. 对任何一棵二叉树 , 如果度为 0 其叶结点个数为n_{0} , 度为 2 的分支结点个数为n_{2},则有n_{0}n_{2}+1.
4. 若规定根节点的层数为 1 ,具有 n 个结点的满二叉树的深度 h=log_{2}(n + 1).
5. 对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从 0 开始编号,则对于序号为i 的结点有:
1. i>0 i 位置节点的双亲序号: (i-1)/2 i=0 i 为根节点编号,无双亲节点.
2. 2i+1<n ,左孩子序号: 2i+1 2i+1>=n 否则无左孩子.
3. 2i+2<n ,右孩子序号: 2i+2 2i+2>=n 否则无右孩子.

2.3、二叉树的实现:

一个二叉树的节点包括三个部分,节点的值,左孩子与右孩子。

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<math.h>
#include<stdbool.h>

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

}TreeNode;

创建一个二叉树的节点并赋值。

TreeNode* BuyTreeNode(int x)
{
	TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
	assert(node);
	node->data = x;
	node->left = node->right = 0;
	return node;
}

 在此基础上创建一个二叉树。

TreeNode* CreateTree()
{
	TreeNode* node1 = BuyTreeNode(1);
	TreeNode* node2 = BuyTreeNode(2);
	TreeNode* node3 = BuyTreeNode(3);
	TreeNode* node4 = BuyTreeNode(4);
	TreeNode* node5 = BuyTreeNode(5);
	TreeNode* node6 = BuyTreeNode(6);
	TreeNode* node7 = BuyTreeNode(7);

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

	return node1;
}

3、二叉树的遍历:

二叉树的遍历是使用递归的方式进行的。

3.1、前序遍历:

void PrevOrder(TreeNode* root)
{
	if (root==NULL)
	{
		printf("N");
		return;
	}
	printf("%d", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
	
}

3.2、中序遍历:

void InOrder(TreeNode* root)
{
	if (root==NULL)
	{
		printf("N");
		return;
	}
	InOrder(root->left);
	printf("%d", root->data);
	InOrder(root->right);
}

3.3、后序遍历:

void BackOrder(TreeNode* root)
{
	if (root == NULL)
	{
		printf("N");
		return;
	}
	BackOrder(root->left);
	BackOrder(root->right);
	printf("%d", root->data);
}

3.4、层序遍历:

层序遍历这里使用了队列的方式。

void LevelOrder(TreeNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
		
	}
	int levelsize = 1;
	while (!QueueEmpty(&q))
	{
		//一层一层出
		while (levelsize--)
		{
			TreeNode* front = QueueFront(&q);
			QueuePop(&q);
			printf("%d", front->data);
			if (front->left)
			{
				QueuePush(&q, front->left);
			}
			if (front->right)
			{
				QueuePush(&q, front->right);
			}
		}
		printf("\n");
		levelsize = QueueSize(&q);
		
	}
	QueueDestroy(&q);
}

  • 39
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菲利普赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值