题目描述
给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。
示例:
输入: 3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
- 递归法
自己想不明白,看了其他人的办法,加了一些注释。需要构建的二叉树数量为卡特兰数,用递归的办法构建子树,不断以i为根节点进行构建子树,最终输出结果
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
//分配动态内存
#ifdef __DEBUG
#define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#endif
struct TreeNode *InsertTree(int n)//建立值为n的子树
{
struct TreeNode *node = NULL;
node = malloc(sizeof(struct TreeNode));
memset(node, 0x0, sizeof(struct TreeNode));//分配内存
if (node == NULL) {
return NULL;
}
node->val = n;//设置节点的值
return node;//返回子树
}
struct TreeNode **buildTree(int left, int right, int level, int *total)
{
struct TreeNode **root = NULL;
struct TreeNode **lnode = NULL;
struct TreeNode **rnode = NULL;
int leftcount = 0;
int rightcount = 0;
int nodecount = 0;
int totalcount = 0;//总子树的长度
int i, j, k;
if (left > right) {//此时树的节点已经到了结尾
totalcount++;
root = realloc(root, sizeof(struct TreeNode **) * totalcount);
root[totalcount - 1] = NULL;//设置最后节点为空
*total = totalcount;
return root;//返回此时的树
}
for (i = left; i <= right; i++) {
nodecount = leftcount = rightcount = 0;
lnode = buildTree(left, i - 1, level + 1, &leftcount);
//对序列 1 ... i-1建立左子树
rnode = buildTree(i + 1, right, level + 1, &rightcount);
//对序列 i+1 ... n建立右子树
nodecount += leftcount * rightcount;//计算卡特兰数
root = realloc(root, sizeof(struct TreeNode **) * (totalcount + nodecount));
for (k = 0; k < leftcount; k++) {
for (j = 0; j < rightcount; j++) {
root[totalcount + (k * rightcount + j)] = InsertTree(i);
//以当前节点为根节点,并设置左右节点
root[totalcount + (k * rightcount + j)]->left = lnode[k];
root[totalcount + (k * rightcount + j)]->right = rnode[j];
}
}
free(lnode);
free(rnode);
totalcount +=nodecount;//加上总子树的数目
if (level == 0) {
DEBUG("done %d\n", totalcount);
}
}
*total = totalcount;
return root;
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
struct TreeNode** generateTrees(int n, int* returnSize)
{
if (returnSize) {
*returnSize = 0;
}
if (n == 0) {
return NULL;
}
return buildTree(1, n, 0, returnSize);
}