【数据结构】二叉树

【数据结构】二叉树

1.什么是二叉树

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分

在这里插入图片描述

2.二叉树的结构与特点

1.二叉树大多以链式结构体现,与链表有相似之处,但又不同

2.二叉树的每个节点最多有两课子树,即深度为h的二叉树中至多含有2^h-1个节点

3.二叉树的子树分为左子树与右子树

在这里插入图片描述

3.二叉树的类型

满二叉树:一个二叉树,如果每层的节点数都达到最大值(即2),则这个二叉树就是满二叉树

在这里插入图片描述

完全二叉树:设一个二叉树的深度为h,其1~h-1层的节点数都到达最大,并且最下层的节点都集中在树的左侧,则该树就是完全二叉树(因此满二叉树是一种特殊的二叉树)

在这里插入图片描述

二叉搜索树(B树)与平衡二叉搜索树(AVL树)就不在这里解释,以上仅介绍基础

4.二叉树的实现

本文以链式结构来实现二叉树,实际上还存在另一种顺序结构(以数组实现)的二叉树,但普通的二叉树不适合用该结构来存储

以下是一个普通二叉树节点的定义

struct BTNode
{
	BTNode* left_BTNode;//指向当前节点的左孩子
	BTNode* right_BTNode;//指向当前节点的右孩子
	char data;
};

二叉树的创建(前序遍历方式创建)

BTNode* Create_BinaryTree(vector<char>& str)//返回的根节点表示该二叉树,str为需要转化为二叉树的数组
{
	if (str[j] == '#')//用j来指向str
	{
		return NULL;
	}
	else
	{
		BTNode* root = new BTNode;
		root->data = str[j];
		j++;
		root->left_BTNode = Create_BinaryTree(str);
		j++;
		root->right_BTNode = Create_BinaryTree(str);
		return root;//返回根节点
	}
}

二叉树的判空

bool IsEmpty(BTNode* root)
{
	if (root == NULL)
		return true;
	else
		return false;
}

二叉树的遍历有基础的三种:前序,中序,后序

二叉树的前序遍历(根节点,左节点,右节点)

在这里插入图片描述

void PreTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	cout << root->data;
	PreTravel(root->left_BTNode);
	PreTravel(root->right_BTNode);
	return;
}

二叉树的中序遍历(左节点,根节点,右节点)

在这里插入图片描述

void MidTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	MidTravel(root->left_BTNode);
	cout << root->data;
	MidTravel(root->right_BTNode);
	return;
}

二叉树的后序遍历(左节点,右节点,根节点)

在这里插入图片描述

void BackTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	BackTravel(root->left_BTNode);
	BackTravel(root->right_BTNode);
	cout << root->data;
	return;
}

除此之外还存在一种层序遍历,需要依靠队列(queue)来实现

二叉树的层序遍历(层层遍历)

在这里插入图片描述

void LevelTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	queue<BTNode*>que;//定义一个队列
	que.push(root);//先将根节点入队
	while (!que.empty())//判断队列是否为空
	{
		int length = que.size();//记录当前队列长度
		for (int i = 0; i < length; i++)//遍历当前层
		{
			auto node = que.front();
			if (node->left_BTNode != NULL)
			{
				que.push(node->left_BTNode);
			}
			if (node->right_BTNode != NULL)
			{
				que.push(node->right_BTNode);
			}
			cout << node->data;
			que.pop();
		}
	}
	return;
}

二叉树求最大深度

int MaxDepth(BTNode* root)
{
	if (IsEmpty(root))
	{
		return 0;
	}
	return max(MaxDepth(root->left_BTNode), MaxDepth(root->right_BTNode)) + 1;//递归求最大深度
}

二叉树的节点查找

BTNode** FindBTNode(BTNode** root, char goal)//这里采取前序遍历查找,同时以二级指针方式传参,是为了后面方便删除节点
{
	if (IsEmpty(*root))
	{
		return NULL;
	}
	if ((*root)->data == goal)
	{
		return &(*root);
	}
	BTNode** ret = FindBTNode(&(*root)->left_BTNode, goal);
	if (ret != NULL)
	{
		return ret;
	}
	ret = FindBTNode(&(*root)->right_BTNode, goal);
	if (ret != NULL)
	{
		return ret;
	}
	return NULL;
}

二叉树的节点数据修改

void ModifyBTNode(BTNode* root, char goal, char newdata)
{
	BTNode** ret = FindBTNode(&root, goal);//由于find函数采用二级指针传递root,这里要对root再取一次地址
	if (ret == NULL)
	{
		cout << "该节点不存在!";
		return;
	}
	(*ret)->data = newdata;
	return;
}

二叉树的节点删除

void DeleteBTNode(BTNode** root, char goal)
{
	BTNode** ret = FindBTNode(root, goal);
	delete(*ret);
	*ret = NULL;//置空该节点
	return;
}

二叉树的销毁

void Destroy_BinaryTree(BTNode** root)
{
	if (IsEmpty(*root))
	{
		return;
	}
	if (!IsEmpty((*root)->left_BTNode))
	{
		Destroy_BinaryTree(&(*root)->left_BTNode);
	}
	if (!IsEmpty((*root)->right_BTNode))
	{
		Destroy_BinaryTree(&(*root)->right_BTNode);
	}
	delete(*root);
	*root = NULL;
	return;
}

完整代码

#include<bits/stdc++.h>

using namespace std;

int j = 0;//在外定义一个全局变量j

struct BTNode
{
	BTNode* left_BTNode;
	BTNode* right_BTNode;
	char data;
};

bool IsEmpty(BTNode* root)
{
	if (root == NULL)
		return true;
	else
		return false;
}

BTNode* Create_BinaryTree(vector<char>& str)
{
	if (str[j] == '#')
	{
		return NULL;
	}
	else
	{
		BTNode* root = new BTNode;
		root->data = str[j];
		j++;
		root->left_BTNode = Create_BinaryTree(str);
		j++;
		root->right_BTNode = Create_BinaryTree(str);
		return root;
	}
}

void PreTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	cout << root->data;
	PreTravel(root->left_BTNode);
	PreTravel(root->right_BTNode);
	return;
}

void MidTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	MidTravel(root->left_BTNode);
	cout << root->data;
	MidTravel(root->right_BTNode);
	return;
}

void BackTravel(BTNode* root)
{

	if (IsEmpty(root))
	{
		return;
	}
	BackTravel(root->left_BTNode);
	BackTravel(root->right_BTNode);
	cout << root->data;
	return;
}

void LevelTravel(BTNode* root)
{
	if (IsEmpty(root))
	{
		return;
	}
	queue<BTNode*>que;
	que.push(root);
	while (!que.empty())
	{
		int length = que.size();
		for (int i = 0; i < length; i++)
		{
			auto node = que.front();
			if (node->left_BTNode != NULL)
			{
				que.push(node->left_BTNode);
			}
			if (node->right_BTNode != NULL)
			{
				que.push(node->right_BTNode);
			}
			cout << node->data;
			que.pop();
		}
	}
	return;
}

int MaxDepth(BTNode* root)
{
	if (IsEmpty(root))
	{
		return 0;
	}
	return max(MaxDepth(root->left_BTNode), MaxDepth(root->right_BTNode)) + 1;
}

BTNode** FindBTNode(BTNode** root, char goal)
{
	if (IsEmpty(*root))
	{
		return NULL;
	}
	if ((*root)->data == goal)
	{
		return &(*root);
	}
	BTNode** ret = FindBTNode(&(*root)->left_BTNode, goal);
	if (ret != NULL)
	{
		return ret;
	}
	ret = FindBTNode(&(*root)->right_BTNode, goal);
	if (ret != NULL)
	{
		return ret;
	}
	return NULL;
}

void ModifyBTNode(BTNode* root, char goal, char newdata)
{
	BTNode** ret = FindBTNode(&root, goal);
	if (ret == NULL)
	{
		cout << "该节点不存在!";
		return;
	}
	(*ret)->data = newdata;
	return;
}

void DeleteBTNode(BTNode** root, char goal)
{
	BTNode** ret = FindBTNode(root, goal);
	delete(*ret);
	*ret = NULL;
	return;
}

void Destroy_BinaryTree(BTNode** root)
{
	if (IsEmpty(*root))
	{
		return;
	}
	if (!IsEmpty((*root)->left_BTNode))
	{
		Destroy_BinaryTree(&(*root)->left_BTNode);
	}
	if (!IsEmpty((*root)->right_BTNode))
	{
		Destroy_BinaryTree(&(*root)->right_BTNode);
	}
	delete(*root);
	*root = NULL;
	return;
}

int main()
{
	vector<char>str;
	for(;;)
	{
		char s = getchar();
		if (s == '\n')
		{
			break;
		}
		str.push_back(s);//输入数据
	}
	BTNode* root = Create_BinaryTree(str);//用root表示二叉树
	PreTravel(root);
	cout << endl;
	MidTravel(root);
	cout << endl;
	BackTravel(root);
	cout << endl;
	LevelTravel(root);
	cout << endl;
	cout << MaxDepth(root)<<endl;
	ModifyBTNode(root, 'A', 'H');
	PreTravel(root);
	cout << endl;
	DeleteBTNode(&root, 'B');
	Destroy_BinaryTree(&root);
	cout << IsEmpty(root);
	return 0;
}

输入ABCD##E###FG##HJ###,按前序遍历生成二叉树图:
在这里插入图片描述

结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值