1.二叉树链式结构的实现
1.1 前置说明
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->_left = node2;
node1->_right = node4;
node2->_left = node3;
node4->_left = node5;
node4->_right = node6;
return node1;
}
注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解。 再看二叉树基本操作前,再回顾下二叉树的概念,详情可见树和堆的一些基础知识
二叉树是:
1.2二叉树的遍历
1.2.1 前序、中序以及后序遍历
按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:
- 1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
- 2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
- 3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后
下面主要分析前序递归遍历,中序与后序图解类似,大家可自己动手绘制。
前序遍历递归图解:
一直往下,遇空返回,再读下一行代码
2.二叉树例题
965.单值二叉树
如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。
只有给定的树是单值二叉树时,才返回 true;否则返回 false。
示例 1:
输入:[1,1,1,1,1,null,1]
输出:true
示例 2:
输入:[2,2,2,5,2]
输出:false
对反例判断完后,就开始递归
class Solution {
public:
bool isUnivalTree(TreeNode* root) {
// 先进行三个反例的判断,就开始递归啦
if (root == NULL)
return true;
// 有且不等于上一个,判错
if (root->left && root->left->val != root->val)
return false;
if (root->right && root->right->val != root->val)
return false;
// 递归
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
};
理解:层层传递,先一条路走到底,NULL之后开始开始往回报,碰到右子树就传过来执行代码了,最后返回到院长为空
二叉树查找值为x的结点
100.相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:
输入:p = [1,2], q = [1,null,2]
输出:false
思路:先左再右,没有不一样就是一样,返回ture
class Solution {
public:
bool isSameTree(TreeNode* p, 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);
//先左再右,没有不一样就是一样,返回ture
}
};
144.二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
int TreeSize(struct TreeNode* root) {
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
void preorder(struct TreeNode* root, int* res, int* resSize) {
if (root == NULL) {
return;
}
res[(*resSize)++] = root->val; // 读取根数据
preorder(root->left, res, resSize); // 读取左子树
preorder(root->right, res, resSize); // 读取右子树
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = TreeSize(root);
int* res = (int*)malloc((*returnSize) * sizeof(int)); // 分配内存
*returnSize = 0;
preorder(root, res, returnSize); // 进行先序遍历
return res;
}
572. 另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
bool isSametree(struct TreeNode* p, struct TreeNode* q) {
if (p == NULL && q == NULL) {
return true;
} else if (p == NULL || q == NULL) {
return false;
} else {
if (p->val != q->val) {
return false;
} else {
return isSametree(p->left, q->left) &&
isSametree(p->right, q->right);
}
}
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
if (subRoot == NULL)
{
return true;
}
else if (root == NULL && subRoot != NULL)
{
return false;
}
if (true == isSametree(root, subRoot))//关键步骤调用空空真函数比较
{
return true;
}
else
{
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);//不断后移比较
}
}