二叉树的基本操作

目录

一.二叉树的结构

二.二叉树的操作

1.二叉树的创建

2.二叉树的销毁

3.二叉树的节点个数

4.二叉树叶子节点个数

5.二叉树第K层的节点数

6,二叉树查找

7.前序遍历

8.中序遍历

9.后序遍历

10.层序遍历

11,判断是否是完全二叉树


一.二叉树的结构

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;
  1. 根节点(Root): 二叉树的顶部节点称为根节点,它是树的起始点。

  2. 节点(Node): 每个节点包含一个数据元素,同时可能有一个指向左子节点和右子节点的指针。

  3. 子节点(Children): 每个节点最多有两个子节点,分别为左子节点和右子节点。

  4. 叶子节点(Leaf): 没有子节点的节点称为叶节点,它们位于二叉树的末端。

  5. 深度(Depth): 从根节点到某个节点的唯一路径上的节点数称为该节点的深度。根节点的深度为0。

  6. 高度(Height): 从某个节点到其最远叶节点的路径上的节点数称为该节点的高度。树的高度即为根节点的高度。

  7. 子树(Subtree): 由一个节点及其所有后代节点组成的集合称为子树。

二叉树一般用链式结构构造

二.二叉树的操作

1.二叉树的创建

BTNode* BuyTreeNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	assert(node);

	node->data = x;
	node->left = NULL;
	node->right = NULL;

	return node;
}
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
	if (a[*pi] == '#')
	{
		(*pi)++;
		return NULL;
	}
	BTNode* newNode = BuyTreeNode(a[*pi]);
	(*pi)++;
	newNode->left = BinaryTreeCreate(a, pi);
	newNode->right = BinaryTreeCreate(a, pi);
	return newNode;
}

BuyTreeNode用来创建新节点,BinaryTreeCreate用来创建整个树,并返回根节点,传入数组a和一个用来控制下标的pi,pi初始是0,

2.二叉树的销毁

void BinaryTreeDestroy(BTNode* root)
{
	if (root == NULL);
		return;
	BinaryTreeDestroy(root->left);
	BinaryTreeDestroy(root->right);
	free(root);
}

使用后序遍历释放每一个节点

3.二叉树的节点个数

int BinaryTreeSize(BTNode* root)
{
	return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

如果为空返回0.否则返回左子树和右子树的节点和加上根节点

4.二叉树叶子节点个数

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

如果是叶子节点就返回1,否则返回左子树和右子树的叶子节点之和

5.二叉树第K层的节点数

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

如果K为1表示当前节点是第K层的节点,返回1,否则返回左子树和右子树的第K-1层的节点数

6,二叉树查找

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
		return NULL;
	if (root->data == x)
		return root;
	BTNode* T1 = BinaryTreeFind(root->left, x);
	BTNode* T2 = BinaryTreeFind(root->right, x);
	if (T1 != NULL)
		return T1;
	if (T2 != NULL)
		return T2;
	return NULL;
}

如果当前节点是要查找的,直接返回,不然就向左子树和右子树找,返回找到的节点,找不到返回空

7.前序遍历

void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
		return;
	printf("%c ", root->data);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

8.中序遍历

void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
		return;
	BinaryTreeInOrder(root->left);
	printf("%c ", root->data);
	BinaryTreeInOrder(root->right);
}

9.后序遍历

void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
		return;
	BinaryTreePostOrder(root->left);
	BinaryTreePostOrder(root->right);
	printf("%c ", root->data);
}

10.层序遍历

void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	int size = 1;
	while (!QueueEmpty(&q))
	{
		while (size--)
		{
			BTNode* front = QueueFront(&q);
			QueuePop(&q);
			if(front->left!=NULL)
				QueuePush(&q, front->left);
			if (front->right != NULL)
				QueuePush(&q, front->right);
			printf("%c ", front->data);
		}
		size = QueueSize(&q);
		printf("\n");
	}
	QueueDestroy(&q);
}

利用队列实现层序遍历,先将根节点入队列,每次出队列都会把其非空左右子树的根节点入队列,

11,判断是否是完全二叉树

int BinaryTreeComplete(BTNode* root)
{

	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
			break;
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front != NULL)
		{
			QueueDestroy(&q);
			return 0;
		}
	}
	QueueDestroy(&q);
	return 1;
}

当取队头元素为空时,说明所有非空节点已经入队列,这时检查后面是否还有非空节点,如果没有,那就是完全二叉树

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值