简体   繁体   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?

I think the main problem lies with pointer also keeping in mind the restriction that I can't return node type pointer.我认为主要问题在于指针还牢记我不能返回节点类型指针的限制。 Please help me find out where am I doing the mistake.请帮我找出我在哪里做错了。 I have commented the other operations of this code and trying to solve this one first.我已经评论了这段代码的其他操作,并试图先解决这个问题。 So the code has switch statements and the irrelevant functions calls have been added as part of comment for now.所以代码有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);
}

The problem is in the while loop descending the tree: you should add else clauses so the next if test is not evaluated with the updated value of ptr :问题出在沿树向下的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;
        }
    }

Note that the flag indicator is redundant as you return directly from the while loop body when you set it to 1 .请注意, flag指示符是多余的,因为当您将其设置为1时,您直接从while循环体return

Note also that the prototypes for the functions called from main should be outside of the body of main so they are visible when the functions are defined and any conflicts can be detected by the compiler.另请注意,从main调用的函数的原型应该在main主体之外,以便在定义函数时它们是可见的,并且编译器可以检测到任何冲突。

Here is a modified version:这是修改后的版本:

#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