
@TOC

1. 二叉树销毁
- 利用分而治之的思想可转化为:
-
- - 返回条件(最小规模子问题):左/右子树为空。
先销毁根再销毁左右——后序查找
实现
1 2 3 4 5 6 7 8 9 10 11
| void destory(BTNode* root) { if (root == NULL) { return 0; } destory(root->left); destory(root->right); free(root); }
|
2. 二叉树查找值为x的值
- 子问题:左/右子树是否为x
- 返回条件:
-
-
-
- 注意:要返回地址,所以每次栈帧销毁都要接收返回值,直到回归第一层。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BTNode* FreeFind(BTNode* root,BTDataType x) { if (root == NULL) { return; } if (root->val == x) { return root; } BTNode* ret = NULL; ret = FreeFind(root->left, x); if (ret) return ret; ret = FreeFind(root->right, x); if (ret) return ret; return NULL; }
|
3. 相同的树
题目:100.相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
- 返回条件:
- 同时为空返回true(子树相同)
- 接下来有其中一端为NULL的情况,所以不可比较val
- 有一个为空返回flase
- 比较val是否相同,不相等则返回false
- 相同返回true
- 注意:在该题中要求子树末端也必须得相同
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if(p==NULL && q==NULL) return true; if(p==NULL || q==NULL) return false; if(p->val!=q->val) return false; return isSameTree(p->left,q->left) && isSameTree(p->right,q->right); }
|
![![[Pasted image 20230916095543.png]]](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
4. 对称二叉树
- 题目:101对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
- 沿用上一题的方法,可以将其改为从第二层开始两子树的左右-右左子树相同的问题。
- 最小递归子问题:
- 左子树的左值是否等于右子树右值
- 左子树的右值是否等于右子树左值
- 返回条件:
- 全为空返回false;
- 相同返回true;
- 不满足子问题返回false;
实现
1 2 3 4 5 6 7 8 9 10 11
| bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if(p==NULL && q==NULL) return true; if(p==NULL || q==NULL) return false; if(p->val!=q->val) return false; return isSameTree(p->left,q->left) && isSameTree(p->right,q->right); }
|
5. 二叉树的前\中\后序遍历
在线编程中属于接口型(另一个是io型,自己编程)
- 题目分析
int* returnSize 返回的是数组大小,形参的改变改变不了实参,故传递指针类型 。
- 题目值类型为
int* ,由于开辟的空间名可自己定义,故返回数组名。
- 我们在内部定义局部变量来放malloc过来的空间
开辟空间大小TreeSize
- 将树中元素按前序放入数组中,中序后序遍历与前序同理(前序方法在另一篇文章中已经讲过,故不在此赘述前中后序)
5.最后将n赋值给*TreeSize并返回数组a;
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
int TreeSize(struct TreeNode* root) { return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1; } void preorder(struct TreeNode* root,int* a,int* pi) { if(root==NULL) return ; a[(*pi)++]=root->val; preorder(root->left,a,pi); preorder(root->right,a,pi); }
int* preorderTraversal(struct TreeNode* root, int* returnSize) { int n=TreeSize(root); int* a=(int*)malloc(sizeof(int)*n); int j=0; preorder(root,a,&j); *returnSize=n; return a; }
|
6. 翻转二叉树
题目:翻转二叉树
- 给你一棵二叉树的根节点
root ,翻转这棵二叉树,并返回其根节点。
分析:
最小递归子问题:左右两子树交换(Swap)
返回条件:将每个节点遍历完后是NULL返回。前序遍历
综上,该程序可大致理解为在前序遍历中的交换左右子树问题
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
void Swap(struct TreeNode** p1,struct TreeNode** p2) { struct TreeNode* tmp=NULL; tmp=*p1; *p1=*p2; *p2=tmp; } void PreOrder(struct TreeNode* root) { if(root==NULL) return ; Swap(&(root->left),&(root->right)); PreOrder(root->left); PreOrder(root->right); } struct TreeNode* invertTree(struct TreeNode* root) { PreOrder(root); return root; }
|
7. 另一颗子树
- 题目: 另一颗子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
题目分析:
最小子问题:
判断当前节点下的子树是否相等,见上文中100.相同的树 问题。
返回条件:
前序遍历每个节点,若相同则判断当下节点子树是否相等
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
bool IsSameTree(struct TreeNode* root, struct TreeNode* subRoot) { if(root==NULL && subRoot==NULL) return true; if(root==NULL || subRoot==NULL) return false; if(root->val != subRoot->val) return false; return IsSameTree(root->left,subRoot->left) && IsSameTree(root->right,subRoot->right); } bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) { if(root == NULL) return false; if(root->val==subRoot->val) { if(IsSameTree(root,subRoot)) return true; } return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot); }
|
8. 层序遍历——队列
先进先出
引入队列结构,将int类型该为树的节点类型
.h在预处理阶段不会被处理。.h文件回去再.cpp文件展开,所以放在结构体声明下面
- 实现过程
root=1时,打印front=1,左右不为空,左2右3入队列,删除队头元素1
root=2时,打印front=2,左右不为空,左4右5入队列,删除队头元素2
root=3时,打印front=3,左右为空,删除队头元素3
root=4时,打印front=4,右不为空,右6入队列,删除队头元素4
………………
![[Drawing 2023-09-23 16.03.53.excalidraw.png]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void LevelOrder(BTNode* root) { Que q; QueInit(&q); if (root) QuePush(&q, root); while (!QueEmpty(&q)) { BTNode* front = QueFront(&q); printf("%d",front->val); if (front->left) QuePush(&q, front->left); if (front->right) QuePush(&q, front->right); QuePop(&q); } printf("\n"); QueDestory(&q); }
|
9. 是否为完全二叉树
完全二叉树:前n-1层都是连续的(走层序遍历非空节点连续)
入到空后面一定没有非空
遍历,有空且后面没有非空时为完全二叉树。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| bool TreeComplete(BTNode* root) { Que q; QueInit(&q);
if (root) QuePush(&q, root); while (!QueEmpty(&q)) { BTNode* front = QueFront(&q); if (front==NULL) break; QuePush(&q, front->left); QuePush(&q, front->right); QuePop(&q); } while (!QueEmpty(&q)) { BTNode* front = QueFront(&q); QuePop(&q); if (front != NULL) { QueDestory(&q); return false; } } QueDestory(&q); return true; }
|
10. 求树的高度
高度——就是最深的一层
1 2 3 4 5 6 7 8
| int treeheight(btnode* root) { if (root == null) return 0; return treeheight(root->left) > treeheight(root->right) ? treeheight(root->left) + 1 : treeheight(root->right) + 1; }
|
//多次调用计算,效率及其地下低下,因为在调用时进行了两次递归,非常差
1 2 3 4 5 6 7 8 9 10
| int Treeheight(BTNode* root) { if (root == NULL) return 0; int leftheight = Treeheight(root->left); int rightheight = Treeheight(root->right);
return leftheight > rightheight ? leftheight + 1 : rightheight + 1; }
|
1 2 3 4 5 6 7 8
| int Treeheight(BTNode* root) { if (root == NULL) return 0;
return fmax(Treeheight(root->left),Treeheight(root->right)) + 1; }
|
fmax记得包含头文件#include<math.h>
11. [KY11 二叉树遍历]
题目 11. KY11 二叉树遍历
![![[Pasted image 20230925193204.png]]](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
分析
- 根据题目要求,对字符串先序遍历(根-左-右)创建二叉树,如图所示;
- 当遇到空
#时为空,返回NULL
![![[Pasted image 20230925193117.png]]](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <stdio.h> #include <stdlib.h>
typedef char BTDataType;
typedef struct BinaryTreeNode { struct BinaryTreeNode* left; struct BinaryTreeNode* right; BTDataType val; }BTNode;
BTNode* CreatTree(char* str, int* pi) { if (str[*pi] == '#') { (*pi)++; return NULL; } BTNode* root = (BTNode*)malloc(sizeof(BTNode)); root->val = str[*pi]; (*pi)++; root->left = CreatTree(str, pi); root->right = CreatTree(str, pi); return root; }
void Inorder(BTNode* root) { if (root == NULL) return; Inorder(root->left); printf("%c ", root->val); Inorder(root->right); }
int main() { char str[100]; scanf("%s", str);
int i = 0; BTNode* root = CreatTree(str, &i); Inorder(root); return 0; }
|
感谢未来大佬们的光顾,创作不易,还请给个免费的赞哦~~❤️❤️❤️