今天来做一道关于二叉搜索树的题。
题目
题解思路
这道题想了很久,没什么思路,看了题解。
尝试写下我的理解:
1.什么是搜索树:简单来说,(在左右子树存在的情况下),左<根<右,左右子树内部同理。
2.题解把这个方法称为回溯法,但是好像没有“错误然后返回的”的过程?所以实质上是:递归的思想:因为从start到end,已经是排好序的。
(1)让在start-end的数都做根,在每一种根情况下,分出左:[start,i-1], 右:[i+1,end],
(2)构造左子树和右子树
(3)左,根,右相连
递归构建左右子树过程以及怎么跳出递归:分出来的左右部分重复(1),把左右的空间不断缩小,直到为空,此时返回上一层,然后在上一层构造出一个空--根-空的小树,然后小树返回上一层作为左或右子树与根连接,然后返回上一层。
代码完成
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
struct TreeNode** f(int start,int end, int* returnSize)
{
if(start>end)
{
//表示这半部分为空,但是仍有长度为1;
* returnSize=1;
struct TreeNode**ret=malloc(sizeof(struct TreeNode*));
ret[0]=NULL;
return ret;
}
*returnSize = 0;//要给returnSize赋初值
//i的选择是从start到end,所以用for循环
struct TreeNode**allroots=malloc(0);//这里应该是设一个空数组
for(int i=start;i<=end;i++)
{
int leftSize;
struct TreeNode**leftTree=f(start,i-1,&leftSize);//可以直接设置一个变量,然后赋值,不用malloc
int rightSize;
struct TreeNode**rightTree=f(i+1,end,&rightSize);
for(int k=0;k<leftSize;k++)//连接左根右
{
for(int j=0;j<rightSize;j++)
{
//把根节点表示出来
struct TreeNode*curroot=malloc(sizeof(struct TreeNode));
curroot->val=i;
curroot->left=leftTree[k];
curroot->right=rightTree[j];
(*returnSize)++;
allroots=realloc(allroots,sizeof(struct TreeNode*)*(*returnSize));
allroots[ (*returnSize)-1]=curroot;
}
}
free(rightTree);
free(leftTree);
}
return allroots;
}
struct TreeNode** generateTrees(int n, int* returnSize) {
if(!n)
{
*returnSize=0;
return NULL;
}
return f(1,n,returnSize);//returnSzie表示返回的结果数组的大小,也就时候最后一共构造了几种二叉搜索树,是需要修改的,需要作为参数引用
}
笔记
1.知识点补充:
struct TreeNode**allroots=malloc(0);//使用malloc分配一个大小0的空间
allroots=realloc(allroots,sizeof(struct TreeNode*)*(*returnSize));//使用realloc,调整原来开辟的空间大小。
格式为:p=realloc(p,size);size为修改后的空间大小
关于malloc,realloc有一篇博文写得很详细,推荐给大家:
2.报错解决:一个整数局部变量,直接定义成指针,在后面使用的过程中出现如下错误。
报错
相信大家很快就找到了原因,leftSize和rightSize的定义不对,这是是开辟一个整数指针,需要指向明确的空间,不能直接定义,要用malloc开辟一个指针空间。修改:
int*leftSize=malloc(sizeof(int));
int*rightSize=malloc(sizeof(int));
除此之外,还有一种写法,不用将leftSize和rightSize定义为指针,使用int leftSize,rightSize,函数要传入其指针时,使用&leftSize、&rightSizej即可。
我经常在这个地方出错,总结一下:要定义一个变量接受别的变量的赋值,不用malloc开辟空间,但是对于一个需要指向明确的指针/数组,必须开辟空间,不然就会出错!