关于#c语言#的问题:每次想实现同一棵二叉排序树的功能都得输入一次该二叉排序树

改了很多遍使用文件的方式:“r,w,w+”,都无法让程序实现文件的输入输出,不然就是读取不了数据,该怎么改?
还有一个问题就是:如何实现同时显示三个测试案例?
比如这里选1再屏幕输入 T:7456189,接着选1,输出二叉排序树的高度,再进行下去实现其它功能只能再输入T;
每次想实现同一棵二叉排序树的功能都得输入一次该二叉排序树,且如果有多个测试案例,则要输入的次数太多,怎么去改善这个问题?


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void SaveFile(BSTree T) {   //文件输出保存
    FILE* fp;
    if ((fp = fopen("test66-output.txt", "w+")) == NULL)
    {
        printf("  >>数据文件不能打开\n");
        return;
    }
    //fprintf(fp, "%g", sum);
    fprintf(fp,"%g",&T);//%g 自动选择合适的表示法
    fclose(fp);
}
void Print(BSTree T) {  //打印输出
    int sel;
    //double sum = 0.0;
    printf("\t\t\t\t\t\t>>#1二叉排序树的高度<<\n");
    printf("\t\t\t\t\t\t>>#2除嵌套括号方式显示二叉排序树以外,增加倒立的树的形式显示<<\n");
    printf("\t\t\t\t\t\t>>#3用递归和非递归实现二叉排序树的查找并给出查找路径<<\n");
    printf("\t\t\t\t\t\t>>#4分别给出测试案例查找成功(如有)和查找失败(如有)次数<<\n");
//    printf("\t\t\t\t\t\t>>#5在等概率的情况下,给出ASL成功(如有)和ASL不成功(如有)的公式和结果<<\n");
    scanf("%d", &sel);
    switch (sel) {
    case 1:
        int h;
        h=height(T);
        printf("\n该二叉排序树的高度为:%d\n",h);
        break;
    case 2:
        printf("\n二叉树的的嵌套括号表示:");
        Show(T);
        printf("\n");
        break;
    case 3:
        printf("\n请输入要查找的元素:");
        int k;
        scanf("%d",&k);
        //ScreenInput();
        printf("\n递归或非递归实现二叉排序树的查找并给出查找路径:");
        SearchBST(T, k);
        printf("\n");
        break;
    case 4:
        printf("\n分别给出测试案例查找成功(如有)和查找失败(如有)次数:\n");
        int sumlen=0,m=0;
        prSucclength(T);
        prUnsucclength(T);
        printf("\n在等概率的情况下,给出ASL成功(如有)和ASL不成功(如有)的公式和结果:\n");
        printf("ASL成功=%g\n",ASLsucc(T));     //ASL = 1/6 * (1+2+2+3+3+3) = 14/6
        printf("ASL不成功=%g\n",ASLunsucc(T));
        break;
        
    printf("\n");
    SaveFile(T);
}
}
void ScreenInput() {  //屏幕输入
    BSTree T;
    printf("T:");CreateBST(&T);//scanf("%d",T);
    //Print(x, n);
    //Print(T,k);
//    int k;
    //printf("k:"); scanf("%d", k);
    Print(T);
}
void FileOpen() {   //文件输入
    FILE* fp = NULL;
    //double x;
    BSTree T;
    int sel;
    printf("\t\t\t\t\t\t>>请选择文件1~3:<<\n");
    scanf("%d", &sel);
    switch (sel) {
    case 1:
        fp = fopen("test66-input1.txt", "r");//r
        break;
    case 2:
        fp = fopen("test66-input2.txt", "r");//r
        break;
    case 3:
        fp = fopen("test66-input3.txt", "r");//r
        break;
    }
    if (fp == NULL) {
        printf("文件不存在\n");
        exit(0);
    }
    else {
        fscanf(fp, "%g", &T);
        //fscanf(fp, "%g", k);
        
        Print(T);
    }
    fclose(fp);
}


int main()
{
    BSTree T;
    //int k;
    BSTree result;
    int sel = 1;
    system("Color F0");//改变DOS窗口颜色 
    while (sel) {
        printf("\t\t\t\t\t\t>>#1屏幕输入<<\n");
        printf("\t\t\t\t\t\t>>#2文件输入<<\n");
        printf("\t\t\t\t\t\t>>#0退出<<\n");
        printf("请选择输入方式:\n");
        scanf("%d", &sel);
        switch (sel) {
        case 1:
            printf("--------->当前为屏幕输入\n");
            ScreenInput();
            break;
        case 2:
            printf("--------->当前为文件输入\n");
            FileOpen();
            break;
        }
    }
    
    
    return 1;
}

基于new Bing的编写:
关于文件输入输出的问题,你可以在文件中存储二叉排序树的结点信息,而不是直接存储整棵树的指针,这样便于读取和输出。具体的实现方式可以参考以下代码:

// 存储二叉排序树结点信息的结构体
typedef struct {
int data;
struct BSTNode* left;
struct BSTNode* right;
}BSTNodeInfo;

void SaveFile(BSTree T) {   // 文件输出保存
FILE* fp;
if ((fp = fopen("test66-output.txt", "w+")) == NULL) {
printf("  >>数据文件不能打开\n");
return;
}

// 将二叉排序树结点信息写入文件
WriteToFile(T, fp);

fclose(fp);
}

void WriteToFile(BSTree T, FILE* fp) {  // 将二叉排序树结点信息写入文件
if (T == NULL) {  // 如果是空树,不做任何操作
return;
}

BSTNodeInfo node;
node.data = T->data;
node.left = T->left;
node.right = T->right;

fwrite(&node, sizeof(BSTNodeInfo), 1, fp);  // 将当前结点信息写入文件

WriteToFile(T->left, fp);  // 递归存储左子树结点信息
WriteToFile(T->right, fp); // 递归存储右子树结点信息
}

void FileOpen() {   //文件输入
FILE* fp = NULL;
BSTree T = NULL;   // 初始化为空树
int sel;
printf("\t\t\t\t\t\t>>请选择文件1~3:<<\n");
scanf("%d", &sel);
switch (sel) {
case 1:
fp = fopen("test66-input1.txt", "r");//r
break;
case 2:
fp = fopen("test66-input2.txt", "r");//r
break;
case 3:
fp = fopen("test66-input3.txt", "r");//r
break;
}
if (fp == NULL) {
printf("文件不存在\n");
exit(0);
}
else {
// 从文件中读取二叉排序树结点信息
ReadFromFile(&T, fp);

    Print(T);
}
fclose(fp);
}

void ReadFromFile(BSTree* pT, FILE* fp) {  // 从文件中读取二叉排序树结点信息
BSTNodeInfo node;
if (fread(&node, sizeof(BSTNodeInfo), 1, fp) == 1) {
*pT = (BSTree)malloc(sizeof(BSTNode));
(*pT)->data = node.data;
(*pT)->left = NULL;
(*pT)->right = NULL;

    ReadFromFile(&((*pT)->left), fp);  // 递归读取左子树结点信息
    ReadFromFile(&((*pT)->right), fp);  // 递归读取右子树结点信息
}
}

关于同时显示三个测试案例的问题,你可以增加一个循环,对每个测试案例都进行一遍操作,不需要每次都重新输入二叉排序树。具体的实现方式可以参考以下代码:

void ScreenInput() {  //屏幕输入
BSTree T;
printf("T:");CreateBST(&T);//scanf("%d",T);

int sel = 1;
while (sel) {
    printf("\t\t\t\t\t\t>>#1二叉排序树的高度<<\n");
    printf("\t\t\t\t\t\t>>#2除嵌套括号方式显示二叉排序树以外,增加倒立的树的形式显示<<\n");
    printf("\t\t\t\t\t\t>>#3用递归和非递归实现二叉排序树的查找并给出查找路径<<\n");
    printf("\t\t\t\t\t\t>>#4分别给出测试案例查找成功(如有)和查找失败(如有)次数<<\n");
    printf("\t\t\t\t\t\t>>#0返回上一级菜单<<\n");
    printf("请选择要进行的操作:\n");
    scanf("%d", &sel);

    switch (sel) {
        case 1:
            int h;
            h = height(T);
            printf("\n该二叉排序树的高度为:%d\n", h);
            break;
        case 2:
            printf("\n二叉树的的嵌套括号表示:");
            Show(T);
            printf("\n");
            break;
        case 3:
            printf("\n请输入要查找的元素:");
            int k;
            scanf("%d", &k);
            printf("\n递归或非递归实现二叉排序树的查找并给出查找路径:");
            SearchBST(T, k);
            printf("\n");
            break;
        case 4:
            printf("\n分别给出测试案例查找成功(如有)和查找失败(如有)次数:\n");
            prSucclength(T);
            prUnsucclength(T);
            printf("\n在等概率的情况下,给出ASL成功(如有)和ASL不成功(如有)的公式和结果:\n");
            printf("ASL成功=%g\n", ASLsucc(T));     //ASL = 1/6 * (1+2+2+3+3+3) = 14/6
            printf("ASL不成功=%g\n", ASLunsucc(T));
            break;
    }
}

SaveFile(T);
}

void FileOpen() {   //文件输入
FILE* fp = NULL;
BSTree T = NULL;   // 初始化为空树
int sel;
printf("\t\t\t\t\t\t>>请选择文件1~3:<<\n");
scanf("%d", &sel);
switch (sel) {
case 1:
fp = fopen("test66-input1.txt", "r");//r
break;
case 2:
fp = fopen("test66-input2.txt", "r");//r
break;
case 3:
fp = fopen("test66-input3.txt", "r");//r
break;
}
if (fp == NULL) {
printf("文件不存在\n");
exit(0);
}
else {
// 从文件中读取二叉排序树结点信息
ReadFromFile(&T, fp);

    int sel2 = 1;
    while (sel2) {
        printf("\t\t\t\t\t\t>>#1二叉排序树的高度<<\n");
        printf("\t\t\t\t\t\t>>#2除嵌套括号方式显示二叉排序树以外,增加倒立的树的形式显示<<\n");
        printf("\t\t\t\t\t\t>>#3用递归和非递归实现二叉排序树的查找并给出查找路径<<\n");
        printf("\t\t\t\t\t\t>>#4分别给出测试案例查找成功(如有)和查找失败(如有)次数<<\n");
        printf("\t\t\t\t\t\t>>#0返回上一级菜单<<\n");
        printf("请选择要进行的操作:\n");
        scanf("%d", &sel2);

        switch (sel2) {
            case 1:
                int h;
                h = height(T);
                printf("\n该二叉排序树的高度为:%d\n", h);
                break;
            case 2:
                printf("\n二叉树的的嵌套括号表示:");
                Show(T);
                printf("\n");
                break;
            case 3:
                printf("\n请输入要查找的元素:");
                int k;
                scanf("%d", &k);
                printf("\n递归或非递归实现二叉排序树的查找并给出查找路径:");
                SearchBST(T, k);
                printf("\n");
                break;
            case 4:
                printf("\n分别给出测试案例查找成功(如有)和查找失败(如有)次数:\n");
                prSucclength(T);
                prUnsucclength(T);
                printf("\n在等概率的情况下,给出ASL成功(如有)和ASL不成功(如有)的公式和结果:\n");
                printf("ASL成功=%g\n", ASLsucc(T));     //ASL = 1/6 * (1+2+2+3+3+3) = 14/6
                printf("ASL不成功=%g\n", ASLunsucc(T));
                break;
        }
    }
}

fclose(fp);
}

不建议你这样print
建议你用逗号分隔存储数组的办法保存二叉树,其中空的数据域用某个特殊符号代替
数组第一个元素存储根节点,然后对于i节点,它的子节点是i2+1和i2+2,递归写入对应的数组位置
(鉴于现在GPT胡乱回答太多,且很多题主好坏不分地胡乱采纳,为节约体力,如果需要详细代码,我可以进一步补充回答)


#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct TreeNode {  
    int val;  
    struct TreeNode *left;  
    struct TreeNode *right;  
} TreeNode;  
  
TreeNode* createNode(int val) {  
    TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode));  
    node->val = val;  
    node->left = NULL;  
    node->right = NULL;  
    return node;  
}  
  
void insert(TreeNode **root, int val) {  
    if (*root == NULL) {  
        *root = createNode(val);  
        return;  
    }  
    TreeNode *cur = *root;  
    while (cur != NULL && cur->val < val) {  
        if (cur->left == NULL) {  
            cur->left = createNode(val);  
            return;  
        }  
        cur = cur->left;  
    }  
    if (cur == NULL) {  
        cur->left = createNode(val);  
        return;  
    }  
    insert(&cur->left, val);  
    insert(&cur->right, val);  
}  
  
void printTree(TreeNode *root) {  
    if (root == NULL) {  
        return;  
    }  
    printTree(root->left);  
    printf("%d ", root->val);  
    printTree(root->right);  
}  
  
int main() {  
    TreeNode *root = NULL;  
    int val;  
    while (scanf("%d", &val) != EOF) {  
        insert(&root, val);  
    }  
    printf("\n");  
    printf("Tree height: %d\n", printTree(root));  
    printf("\n");  
  `createNode`函数用于创建一个新的节点,`insert`函数用于向二叉排序树中插入一个节点,`printTree`函数用于打印二叉排序树的节点值。在`main`函数中,我们使用`scanf`函数从标准输入中读取二叉排序树的节点值,并使用`printTree`函数打印二叉排序树的节点值。  
  
对于第二个问题,可以考虑使用循环来实现同时显示三个测试案例。具体实现方法可以参考下面的代码:  
  
  
```c  
#include <stdio.h>  
  
int main() {  
    int val;  
    printf("Please input the value of T: ");  
    scanf("%d", &val);  
    if (val == 1) {  
        printf("The height of the binary tree is: %d\n", printTree(root));  
    } else if (val == 2) {  
        printf("The height of the binary tree is: %d\n", printTree(root->left));  
        printf("The height of the binary tree is: %d\n", printTree(root->right));  
    } else {  
        printf("Please input the value of T: ");  
        scanf("%d", &val);  
        printf("The height of the binary tree is: %d\n", printTree(root));  
    }  
    return 0;  
}
不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/1061034
  • 以下回答来自chatgpt:

    由于参考资料与问题存在较大的不符,因此无法直接回答问题。建议重新提交问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^