1.二叉树k层结点个数
2.二叉树查找值为x的结点
3.二叉树基础oj练习
1.二叉树k层结点个数
设置k值,k层到1结点的值是k-1,所以1结点到k层的结点也是k-1的距离(高度),这样就可以每下一层就把k值减少一个单位,直到k值为一时就说明到了k层,利用递归过程,每递归一次k值减少一,到k层就返回一上去。
int TreeLevelKSize(BTNode* root, int k)
{
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return TreeLevelKSize(root->left, k - 1) + TreeLevelKSize(root->right, k - 1);
}
2.二叉树查找值为x的结点
要查找二叉树的值,需要去遍历二叉树,去对比设置值与二叉树的值是否相等
代码实现:
首先判断是否为NULL,才能继续下面的操作,再去判断值是否相等,不相等则往下继续对比,利用递归的操作去往下遍历对比,需要创建临时变量去接收返回来的值,不创建的话找到了却不收等于白找,再判断接收的值是否为NULL,不为NULL就说明找到对应的结点,return执行,不去右子树去查找,已经得到了,还需要注意一点是,最后要加一个返回NULL,不加的话是有问题的,要所有的控制路径都有返回值。
BTNode* TreeFind(BTNode* root, int x)
{
if (root == NULL)
{
return NULL;
}
if (root->data == x)
{
return root;
}
BTNode* a = TreeFind(root->left, x);
if (a)
{
return a;
}
BTNode* b = TreeFind(root->right, x);
if (b)
{
return b;
}
return NULL;
}
3.二叉树基础oj练习
1.题目一:
题解:
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);
}
分析:
首先先判断俩个树是否为空树,如果都是空树的话那也算是相等的树,接着判断俩个树是否存在其中一个为空树的情况,这里使用的是||逻辑与,是因为第一个判断已经排除了俩个都为空的情况,所以此判断是排除其中一个为NULL的情况,未触发前面的判断则说明俩个树都存在不为NULL,就开始判读它们的值是否相等,这里要有!=是因为用==就要return true,但是只判断了这个结点相等是不行的,后面的结点还没有判断,所以不能那么早就返回true,最后的返回是次结点的值相等要去下面的左右子树进行判断是否相等,这里用&&逻辑或是要左右子树都是true才行,一层一层往下走所有相等就会把true往上返回,俩个true则说明左右子树的结点值都相等。
2.题目二:
题解:
int TreeNode(struct TreeNode* root)
{
if(root==NULL)
return 0;
return TreeNode(root->left)+TreeNode(root->right)+1;
}
void PrevOver(struct TreeNode* root,int* a,int* i)
{
if(root==NULL)
return;
a[(*i)++]=root->val;
PrevOver(root->left,a,i);
PrevOver(root->right,a,i);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize=TreeNode(root);
int* a=(int*)malloc(sizeof(int*)*(*returnSize));
int i=0;
PrevOver(root,a,&i);
return a;
}
分析:
首先参数给的是根结点的地址和一个int*类型的变量,因为要用malloc去开辟空间使用,虽然题目提到了结点的范围,可以直接申请最大范围的空间,但是也可以通过计算结点的个数去按需申请空间,用returnSize来接收树的结点个数,在创建一个数组去接收以前序组成树的值,还需要创建一个函数去把树的值传个数组,这里需要传&i是因为可以积累i的值,不传地址传值的话会导致数组对应位置的值不正确,因为i的值没有得到积累,递归过程中虽然都是i,但是每个递归都是在新的栈区上开辟空间,是名字相同但是是不同的变量,赋值给数组的还需要判断是否为NULL,NULL是不赋给数组的,数组只接收有效的数字,传完这个结点的值之后,通过递归找到下面的结点去接收下面结点的值,函数结束后把接收完的数组a返回就完成了。
3.题目三:
题解:
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);
}
bool isSubtree(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&&isSameTree(root,subRoot))
return true;
return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}
分析:这道题跟判断俩个树是否相等有相似之处,变成了子树是否与另一个树相等,先判断俩个树是否为空,再判断根结点的值是否相等,并且下面的左右子树都相等才返回true,所以要用逻辑或在根值相等于判断左右子树相等的中间,判断左右子树的函数是判断俩个树是否相等时用的函数,最后的返回是左右子树去调用isSubtree,因为这个结点的值不相等,可能下面的结点满足情况,用递归去往下判断。