【输入形式】按先序序列输入二叉树各结点的值,结点值是正整数,空子树输入-1值。 【输出形式】是二叉排序树输出字符串YES,否者,输出NO
时间: 2024-12-20 22:31:15 浏览: 11
要根据给定的先序遍历顺序构建一棵二叉排序树并判断是否为有效的二叉排序树(即每个节点的值都大于其左子树中的所有节点的值,并且小于其右子树中的所有节点的值),你可以按照以下步骤进行:
1. 创建一个 `TreeNode` 结构体,包含一个整数值 `val` 和两个指向左右孩子的指针 `left` 和 `right`。
```c
typedef struct TreeNode {
int val;
struct TreeNode *left, *right;
} TreeNode;
```
2. 实现一个函数 `buildBST` 来根据先序遍历序列构建二叉树。这个函数接受一个整数数组 `preorder`、一个当前处理到的索引 `index`(初始化为0),以及一个表示当前根节点的临时指针 `root`(初始为空)。
```c
TreeNode* buildBST(int preorder[], int index, TreeNode** root) {
// 如果遍历结束或遇到 -1,返回 NULL
if (index >= sizeof(preorder) || preorder[index] == -1) {
return NULL;
}
// 当前元素将成为新根节点
TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
node->val = preorder[index];
// 更新根节点
*root = node;
// 继续对左子树和右子树递归调用
node->left = buildBST(preorder, index + 1, &node->left);
node->right = buildBST(preorder, index + 1 + node->val, &node->right);
return node;
}
```
3. 定义一个辅助函数 `isValidBST` 来检查是否为有效的二叉排序树。这个函数使用中序遍历的性质,因为对于二叉排序树来说,中序遍历的结果应当是有序的。如果中序遍历结果无效,则说明不是有效的二叉排序树。
```c
int isValidBST(TreeNode* root) {
if (root == NULL) {
return 1; // 空树视为有效
}
int left_valid = isValidBST(root->left);
if (!left_valid) {
return 0;
}
int in_order_valid = inorderTraversal(root);
if (!in_order_valid) {
return 0;
}
return isValidBST(root->right);
}
// 中序遍历辅助函数,返回一个布尔值表示是否有序
int inorderTraversal(TreeNode* node) {
if (node == NULL) {
return 1;
}
return inorderTraversal(node->left) && node->val > inorderTraversal(node->right);
}
```
4. 主函数中,首先创建一个先序遍历数组并调用 `buildBST` 函数生成树,然后调用 `isValidBST` 判断是否为有效的二叉排序树。
```c
int main() {
int preorder[] = {8, 5, 10, 1, 6, 14, 4, -1, 7, 13};
TreeNode* root = NULL;
if (isValidBST(buildBST(preorder, 0, &root))) {
printf("YES\n");
} else {
printf("NO\n");
}
return 0;
}
```
阅读全文