🎁个人主页:我们的五年
🔍系列专栏:C++课程学习
🎉欢迎大家点赞👍评论📝收藏⭐文章


目录
前言:
学了那么久的二叉树,现在基本的二叉树学的差不多了,现在就给大家带来二叉树的几个基本函数。函数有几个,但是基本都不难,基本就是用了分治,递归的思想,画递归展开图也是一种很好理解递归过程好方法,等熟悉以后,就对递归有了更深的理解,面对有一些问题就直接可以写出来。
//二叉树的节点结构类型
typedef struct BinaryTreeNode {
BTDataType data;
struct BinaryTreeNode* left; //左孩子节点的地址
struct BinaryTreeNode* right; //右孩子的地址
}BTNode;每个父节点都包:
1.含存储的数据。
2.左孩子地址。
3.右孩子节点的地址。
画递归展开图也是很好理解的,先创建父亲节点,然后往左走,遇到‘#’,就返回NULL,返回上一层。
- //根据数组创建二叉树,下面举例的是字符数组,创建的顺序是前序遍历
- BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
- {
- if (a[*pi] == '#')
- {
- (*pi)++;
- return NULL;
- }
- BTNode* root = (BTNode*)malloc(sizeof(BTNode));
- root->data = a[*pi]; //前序遍历,先创建中间根节点
- (*pi)++;
- root->left = BinaryTreeCreate(a,pi); //左子树
- root->right = BinaryTreeCreate(a,pi); //右子树
- return root; //返回root节点
- }
销毁二叉树也可以前序遍历删除,也可以中序删除。不过如果是前序删除,就要在先保存左右孩子的节点。如果是中序删除,就是要保存右节点。
只有后序遍历删除不要保存节点。
- // 二叉树销毁
- void BTDestory(BTNode** root)
- {
- if (*root == NULL)
- return;
- //后序遍历销毁二叉树
- BTDestory(&(*root)->left);
- BTDestory(&(*root)->right);
- free(*root);
- *root = NULL;
- }
前序遍历和中序遍历和后序遍历基本差不多,只有后面的两个函数和打印的顺序不一样。
- //前序遍历
- void BTPreOreder(BTNode* root)
- {
- if (root == NULL)
- {
- printf("# ");
- return;
- }
- printf("%c ",root->data);
- BTPreOreder(root->left);
- BTPreOreder(root->right);
- }
分治思想也是yyds
- // 二叉树节点个数
- int BTSize(BTNode* root)
- {
- if (root == NULL)
- return 0;
- //个数等于左树节点个数+右树节点个数+1
- return BTSize(root->left)+BTSize(root->right)+1;
- }
分治
- // 二叉树叶子节点个数
- 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);
- }
要注意的是,遇到NULL,要返回,还有就是,k==1,return 1,要在后面,因为如果在前面,k确实等于1。但是这时候是空节点,所以不能return 1,所以return 1要在后面。
- // 二叉树第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);
- }
找父节点,父节点不是,就去左树,左树没有,就去右树。
只要找到了就返回,所以是或的关系;
- // 二叉树查找值为x的节点
- BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
- {
- if (root == NULL)
- return NULL;
- if (root->data == x)
- return root;
- BTNode* p1 = BinaryTreeFind(root->left, x);
- if (p1!=NULL)
- return p1;
- BTNode* p2 = BinaryTreeFind(root->right, x);
- if (p2!=NULL)
- return p2;
- return NULL;
- }
先在队列中插入root,在队列头出一个数据,就入这个节点的左右孩子节点。因为队列有先进先出的特点,所以能达到层序的目的。
- // 层序遍历
- void BinaryTreeLevelOrder(BTNode* root)
- {
- Queue ps;
- QueueInit(&ps);
- QueuePush(&ps, root);
- while (!QueueEmpty(&ps))
- {
- BTNode* node = QueueTop(&ps);
- if (node == NULL)
- {
- break;
- }
- else
- {
- printf("%c ", node->data);
- QueuePush(&ps, node->left);
- QueuePush(&ps, node->right);
- }
- QueuePop(&ps);
- }
- QueueDestroy(&ps);
- }
先入数据,然后出,和层序遍历一样,当需要NULL就结束。然后看后面的队列是否都是NULL,如果只要有一个不是NULL,那肯定就不是完全二叉树了,前面都有NULL,后面又出现节点。
- // 判断二叉树是否是完全二叉树
- int BinaryTreeComplete(BTNode* root)
- {
- Queue ps;
- QueueInit(&ps);
- QueuePush(&ps, root);
- while (!QueueEmpty(&ps))
- {
- BTNode* node = QueueTop(&ps);
- if (node == NULL)
- {
- break;
- }
- else
- {
- QueuePush(&ps, node->left);
- QueuePush(&ps, node->right);
- }
- QueuePop(&ps);
- }
- while (!QueueEmpty(&ps))
- {
- BTNode* node = QueueTop(&ps);
- if (node != NULL)
- return 0;
- QueuePop(&ps);
- }
- return 1;
- }