Ошибка в коде говорит, что невозможно преобразовать bstNode * в bstNode **. Я использую концепцию двойного указателя здесь вместе с рекурсией - PullRequest
1 голос
/ 13 февраля 2020
    #include<stdio.h>
    #include<stdlib.h>


     struct bstNode
     {
     int data;
     struct bstNode *left;
     struct bstNode *right;
     };



     struct bstNode* getNewNode(int data)
     {
     struct bstNode* newNode = (struct bstNode*)malloc(sizeof(struct bstNode));
      newNode->data = data;
     newNode->left = newNode->right = NULL;
     return newNode;
     }

     void Insert(struct bstNode** root, int data)
     {
        if(*root == NULL)
       {
           *root = getNewNode(data);
     }

     else
     if(data >= (*root)->data)
     {
         Insert((*root)->right, data);
     }
     else
     {
         Insert((*root)->left, data);
     }
 }

 void Search(struct bstNode** root,int data)
 {
     if(data == (*root)->data)
     {
         printf("Data Found");
         getchar();
         exit(0);
     }

     else
     if(data >= (*root)->data)
     {
         Search((*root)->left, data);
     }
     else
     {
         Search((*root)->right, data);
     }
 }

 int main()
 {
     struct bstNode* root = NULL;
     Insert(&root,12);
     Insert(&root,13);
     Insert(&root,1);
     Insert(&root,16);
     Insert(&root,8);
     Insert(&root,19);

     Search(&root,8);
     Search(&root,6);

     return 0;
 }

В приведенном выше коде я пытаюсь передать адрес переменной указателя из главной функции в функцию вставки. Насколько мне известно, здесь он должен принимать аргументы в качестве указателя на указатель, но он не принимает , В чем проблема ? Пожалуйста, помогите, чтобы я тоже мог обновить свои знания. Спасибо.

Подробная ошибка выглядит следующим образом:

main. cpp: В функции 'void Insert (bstNode **, int)': main. cpp: 32: 37: ошибка: невозможно преобразовать 'bstNode *' в 'bstNode **' для аргумента '1' в 'void Insert (bstNode **, int)' Insert ((*root) -> right, data); ^

main. cpp: 36: 36: ошибка: невозможно преобразовать 'bstNode *' в 'bstNode **' для аргумента '1' в 'void Insert (bstNode **, int)' Insert ( (*root) -> слева, данные); ^ main. cpp: В функции 'void Search (bstNode **, int)': main. cpp: 52: 36: ошибка: невозможно преобразовать 'bstNode *' в 'bstNode **' для аргумента '1' 'void Search (bstNode **, int)' Search ((*root) -> left, data); ^

main. cpp: 56: 37: ошибка: невозможно преобразовать 'bstNode *' в 'bstNode **' для аргумента '1' в 'void Search (bstNode **, int)' Search ( (*root) -> верно, данные); ^

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Если в выражениях ваших функций, таких как это

 if(data >= (*root)->data)
 {
     Insert((*root)->right, data);
 }
 else
 {
     Insert((*root)->left, data);
 }

, например, выражение (*root)->right имеет тип struct bstNode*, но функция ожидает аргумент типа struct bstNode**. Измените это утверждение и подобные утверждения, такие как

     Insert( &(*root)->right, data);
1 голос
/ 13 февраля 2020

ОБЪЯСНЕНИЕ

Вы пропустили & до (*root)->left и (*root)->right при множественных вызовах функций Insert и Search. Я изменил вашу программу и добавил требуемый & адрес операторов. Теперь он компилируется нормально.

Но опубликованный вами код приводит к ошибке сегментации, даже после устранения ошибок типа. Это потому, что, как я уже упоминал в моих комментариях, в вашей программе было несколько логических ошибок . Я перечислил их ниже:

  • Вы не указали критерии завершения для рекурсии внутри функции Search. В результате рекурсивный поиск привел к Segmentation Fault.

  • Вы использовали неправильные аргументы для рекурсивного вызова функции Search внутри else if и else. Если data < *root -> data, это означает, что текущий элемент (*root -> data) больше по сравнению со значением, которое вы ищете, и, следовательно, вам нужно заглянуть дальше в левое поддерево и пропустить правый подпункт -tree. Дело становится противоположным, когда data > *root -> data. Но вы искали в правом поддереве, когда data < *root -> data и наоборот. Это привело к неправильному поиску.

  • Хотя это не ошибка, вы используете exit(0), когда вы найдете искомое значение в BST. Это немедленно прекратит работу программы и, следовательно, вы можете использовать Search внутри основной функции только один раз, если значение присутствует в BST.

  • У вас не было сообщения, указывающего, что значение отсутствует в BST.

Внесенные мной изменения включают в себя:

  • Условие завершения для рекурсивного поиска внутри функции Search, т.е. проверка равна *root == NULL

  • Обмен аргументами для рекурсивных Search вызовов.

  • Добавление сообщения, чтобы определить, когда значение не является присутствует в BST

  • Добавлен комментарий Поиск для проверки значения, отсутствующего в BST

Ниже приведена окончательная рабочая версия вашего кода с модификации. Я бы посоветовал вам избавиться от exit(0) и заменить его другим механизмом.

МОДИФИЦИРОВАННЫЙ КОД РАБОТЫ

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

    struct bstNode
    {
        int data;
        struct bstNode *left;
        struct bstNode *right;
    };

    struct bstNode *getNewNode(int data)
    {
        struct bstNode *newNode = (struct bstNode *)malloc(sizeof(struct bstNode));
        newNode->data = data;
        newNode->left = newNode->right = NULL;
        return newNode;
    }

    void Insert(struct bstNode **root, int data)
    {
        if (*root == NULL)
        {
            *root = getNewNode(data);
        }

        else if (data >= (*root)->data)
        {
            Insert(&((*root)->right), data);
        }
        else
        {
            Insert(&((*root)->left), data);
        }
    }

    void Search(struct bstNode **root, int data)
    {
        if (*root != NULL)
        {
            if (data == (*root)->data)
            {
                printf("Data Found");
                getchar();
                exit(0);
            }

            else if (data > (*root)->data)
            {
                Search(&((*root)->right), data);
            }
            else
            {
                Search(&((*root)->left), data);
            }
        }
    }

    int main()
    {
        struct bstNode *root = NULL;
        Insert(&root, 12);
        Insert(&root, 13);
        Insert(&root, 1);
        Insert(&root, 16);
        Insert(&root, 8);
        Insert(&root, 19);

        Search(&root, 8);
        // Search(&root, 29);
        printf("Data Not Found");

        return 0;
    }

Здесь является рабочим решением, достигающим той же цели, без использования двойных ссылок (**).

МОЕ РЕШЕНИЕ

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

struct node
{
    int data;
    struct node *left;
    struct node *right;
};

struct node *createNode(value){
    struct node *newNode = malloc(sizeof(struct node));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}


struct node *insert(struct node *root, int data)
{
    if (root == NULL) return createNode(data);

    if (data < root->data)
        root->left  = insert(root->left, data);

    else if (data > root->data)
        root->right = insert(root->right, data);   

    return root;
}

void search(struct node *root, int data, int *found){
    if(root == NULL) return;

    search(root->left, data, found);

    if(root->data == data){
        *found = 1;
    } 

    search(root->right, data, found);
}

int main(){
    struct node *root = NULL;

    root = insert(root, 8);
    insert(root, 3);
    insert(root, 1);
    insert(root, 6);
    insert(root, 7);
    insert(root, 10);
    insert(root, 14);
    insert(root, 4);

    int found7 = 0, found9 = 0;
    search(root, 7, &found7);
    search(root, 9, &found9);

    found7 ? printf("7 found in BST\n") : printf("7 not found\n");

    found9 ? printf("9 found in BST\n") : printf("9 not found\n");

    return 0;
}
...