来自预序遍历的二叉搜索树以及有关左右节点的信息

Binary search tree from pre-order traversal and information about left and right nodes

提问人:kharevbv 提问时间:11/1/2021 最后编辑:kharevbv 更新时间:11/2/2021 访问量:177

问:

需要验证给定的预购遍历是否为 BST?包含二叉树的预序遍历的文件的输入,以及节点是否具有左、右、两个或没有子节点。例如

-2 3
-4 3
-5 0
-3 0
 2 3
 0 3
-1 0
 1 0
 5 1
 4 0

表示“-2”节点同时具有左子节点和右子节点。“-5”没有孩子。基本上

0 -> no children
1 -> right child
2 -> left child
3 -> both Children

这是无法修改的节点结构


    typedef struct _Tnode {
       int key;
       int height;
       struct _Tnode *left;
       struct _Tnode *right;
    } Tno

PS:在此示例中,它不是BST。我可以用它构建的树看起来像这样

                            -2 
                          /    \
                        /        \
                      -4          2
                      / \        /  \
                    -5   -3     0    5
                               / \    \
                             -1   1    4
c 数据结构 二进制搜索树 AVL-树

评论

0赞 Some programmer dude 11/1/2021
请花一些时间刷新帮助页面,参加 SO 导览,阅读如何提问,以及此问题清单。最后,请编辑您的问题以改进它,例如实际提出问题......你有什么问题?你有没有一个最小的可重复的例子来证明你自己的尝试?你有什么问题?
0赞 kharevbv 11/1/2021
我花了相当多的时间研究这个问题,但没有找到任何解决方案。同时更新问题

答:

1赞 trincot 11/1/2021 #1

您可以使用递归函数来解析输入并检查每个值是否在可接受的范围内。实际上并不需要使用以下类型实际构建树:Tno

#include <stdio.h>
#include <limits.h>

int isBST(min, max) {
    int value, flags;
    scanf("%d %d", &value, &flags);
    if (value < min || value > max) return 0;
    if ((flags > 1) && !isBST(min, value)) return 0;
    if ((flags % 2 > 0) && !isBST(value, max)) return 0;
    return 1;
}

int main(void) {
    int result = isBST(INT_MIN, INT_MAX);
    if (result) printf("This BST is fine\n");
    else        printf("Not a valid BST\n");
    return 0;
}

构建树

如果您需要构建树,然后才验证它是否是 BST,那么您可以按照以下方法执行此操作:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct _Tnode {
    int key;
    int height;
    struct _Tnode *left;
    struct _Tnode *right;
} Tno;

Tno* createNode(int key) {
    Tno* node = malloc(sizeof(Tno));
    node->key = key;
    node->left = node->right = NULL;
    return node;
}

Tno* discardTree(Tno* node) {
    if (node == NULL) return NULL;
    discardTree(node->left);
    discardTree(node->right);
    free(node);
    return NULL;
}

Tno* createTreeFromInput() {
    int value, flags;
    scanf("%d %d", &value, &flags);
    Tno* node = createNode(value);
    if (flags > 1) node->left = createTreeFromInput();
    if (flags % 2 > 0) node->right = createTreeFromInput();
    return node;
}

int isBST(Tno* node, int min) {
    if (node == NULL) return min;
    if (node->key < min) return INT_MAX; // Indication of error
    min = isBST(node->left, min);
    if (min > node->key) return INT_MAX;
    return isBST(node->right, node->key);
}

int main(void) {
    Tno* root = createTreeFromInput();
    int ok = isBST(root, INT_MIN) < INT_MAX;
    if (ok) printf("This BST is fine\n");
    else    printf("Not a valid BST\n");
    discardTree(root);
    return 0;
}

评论

0赞 kharevbv 11/1/2021
我肯定会尝试这个解决方案,但是我想构建树的原因是,以后我还想检查每个节点的余额以确定树是否是AVL?
0赞 trincot 11/2/2021
好吧,但这不是你的问题,对吧?如果您无法证明输入树是否是平衡的 AVL 树,那么这将是一个新问题。
0赞 trincot 11/2/2021
嗯。。。由于缺乏反应,我在回答中添加了一个部分。让我知道这是否是您要找的。
0赞 trincot 11/3/2021
对此添加内容有任何反馈吗?