繁体   English   中英

我试图通过使用双指针在 C 中实现 bst 插入操作,但在下面的代码中出现分段错误,idk 为什么?

[英]I am trying to implement bst insertion operations in C by using double pointer but getting a segmentation fault in the code below, idk why?

我认为主要问题在于指针还牢记我不能返回节点类型指针的限制。 请帮我找出我在哪里做错了。 我已经评论了这段代码的其他操作,并试图先解决这个问题。 所以代码有switch语句,不相关的函数调用现在已添加为注释的一部分。

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

typedef struct tree {  //definition of structure
    int info;
    //char *Name;  
    struct tree *left;
    struct tree *right;
} tree;

int main()
{
    int flag;
    int choice1, item;
    char ch;

    int main_menu(int *choice1);
    int insert(tree **root, int item);
    int display(tree *root);
  
    tree *root = NULL;

    while (1) {
        system("clear");

        main_menu(&choice1);//calling function to display original menu list

        switch (choice1) {
          case 1:
            printf("\nEnter number to be inserted:");
            scanf("%d", &item);
            insert(&root, item);
            break;
          case 2:
            //delete();
            break;
          case 3: 
            //search();
            break;
          case 4:
            //printf("\nTerminating code.....");
            display(root);
            //return(1);
            break;
      
          default:
            printf("\nInvalid choice!!");
            break;
        }
        getchar();
        printf("Enter y to continue");
        ch = getchar();
        if (ch != 'y')
            break;
    }
    return (1);
}

int main_menu(int *choice1) {
    printf("\t\tThe main menu of operations are listed below ");//showing menu

    printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");

    printf("\n\nEnter choice:");
    scanf("%d", &*choice1);//taking choice of user as input
    return (1);
}

tree *getnode(int item) { //function to create node and returning node pointer
    tree *p;
    p = (tree *)malloc(sizeof(tree));
  
    p->right = NULL;
    p->left = NULL;
    p->info = item;
 
    return (p);
}

int insert(tree **root, int item) {
    tree *ptr, *ptr1, *new;
    int flag;
  
    flag = 0;
    new = getnode(item);
    if (*root == NULL) {
        *root = new;
        (*root)->left = NULL;
        (*root)->right = NULL;
    } else {
        ptr = *root;
        while ((ptr != NULL) && (flag == 0)) { 
            ptr1 = ptr;
            if (item < ptr->info) { 
                ptr = ptr->left;
            }
            if (ptr->info == item) {   
                flag = 1;
                printf("\nalready present");
                return (1);
            }
            if (item > ptr->info) {
                ptr = ptr->right;
            }
        }
   
        /*if (ptr == NULL) {
            new = getnode(item);
        }*/
        if (ptr1->info < item) {
            ptr1->right = new;
        } else {
            ptr1->left = new;
        }
    }  
    return (1);
}

问题出在沿树向下的while循环中:您应该添加else子句,以便不使用ptr的更新值评估下一个if测试:

    while ((ptr != NULL) && (flag == 0)) { 
        ptr1 = ptr;
        if (item < ptr->info) { 
            ptr = ptr->left;
        } else
        if (ptr->info == item) {   
            flag = 1;
            printf("\nalready present");
            return (1);
        } else
        if (item > ptr->info) {
            ptr = ptr->right;
        }
    }

请注意, flag指示符是多余的,因为当您将其设置为1时,您直接从while循环体return

另请注意,从main调用的函数的原型应该在main主体之外,以便在定义函数时它们是可见的,并且编译器可以检测到任何冲突。

这是修改后的版本:

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

typedef struct tree {
    int info;
    //char *Name;  
    struct tree *left;
    struct tree *right;
} tree;

int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);

// read and discard the rest of the input line
// return EOF at end of file
int flush_input(void) {
    int ch;
    while ((ch = getchar()) != EOF && ch != '\n')
        continue;
    return ch;
}
  
int main() {
    int flag, choice1, item, ch;
    tree *root = NULL;

    for (;;) {
        system("clear");

        main_menu(&choice1);  //calling function to display original menu list

        switch (choice1) {
          case 1:
            printf("\nEnter number to be inserted: ");
            if (scanf("%d", &item) != 1) {
                flush_input();
                break;
            }
            flush_input();
            insert(&root, item);
            break;
          case 2:
            //delete();
            break;
          case 3: 
            //search();
            break;
          case 4:
            //printf("\nTerminating code.....");
            display(root);
            //return(1);
            break;
          default:
            printf("\nInvalid choice!!");
            break;
        }
        printf("Enter y to continue: ");
        /* read and discard the rest of the input line */
        ch = getchar();
        flush_input()
        if (ch != 'y')
            break;
    }
    return 0;
}

int main_menu(int *choice1) {
    printf("\t\tThe main menu of operations are listed below ");//showing menu
    printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
    printf("\n\nEnter choice:");
    *choice1 = -1;        //default input incase of scanf failure
    scanf("%d", choice1); //taking choice of user as input
    flush_input();        // discard rest of the line
    return 1;
}

tree *getnode(int item) { //function to create node and returning node pointer
    tree *p = (tree *)malloc(sizeof(tree));
  
    p->right = NULL;
    p->left = NULL;
    p->info = item;
 
    return p;
}

int insert(tree **root, int item) {
    tree *new, *ptr, *ptr1;

    ptr1 = ptr = *root;
    while (ptr != NULL) { 
        ptr1 = ptr;
        if (item < ptr->info) { 
            ptr = ptr->left;
        } else
        if (item > ptr->info) {
            ptr = ptr->right;
        } else {   
            printf("\nalready present\n");
            return 1;
        }
    }
    new = getnode(item);
    if (ptr1 == NULL) {
        *root = new;
    } else
    if (ptr1->info < item) {
        ptr1->right = new;
    } else {
        ptr1->left = new;
    }
    return 1;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM