二进制搜索树在有效输入时意外崩溃

时间:2016-03-13 23:51:25

标签: c binary-search-tree

程序应该在二叉搜索树中进行基本操作,例如搜索项目,添加新元素等等。但是,即使在有效输入时,它也经常崩溃。

  JPanel displayPanelVar = new displayPanel();

应加载输入树。

/* Edit: Translated the symbols from Portuguese into
 * English for readibility's sake. Please base any
 * answers upon the original post, as I could have made
 * something wrong in the process. I translated string
 * literals, too, and that may cause input to the original
 * program to become invalid. Again, read the original post.
 *  - KemyLand
 */

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

#define MAXP 40
#define MAXT 100

typedef enum
{
    false,
    true
} bool;

struct node
{
    char *word, *translation;
    bool marker;
    struct node *leftChild;
    struct node *rightChild;
};

void loader(char *word, char *translation);
void add(char *word, char *translation);
void mark(char *word);
void alphanum_list();
void mark_list();
struct node *root = NULL;
struct node* search(char *word);
struct node* load();


int main()
{
    char word[MAXP];
    char translation[MAXT];
    char option[15];

    while(1)
    {
        scanf("%s", option);
        printf("%s", option);

        if(strcmp(option, "LOAD") == 0) {
            load();
        } else if(strcmp(option, "ADD") == 0) {
            scanf("%s", word);
            scanf("%s", translation);
            load(word, translation);
        } else if(strcmp(option, "SEARCH") == 0) {
            scanf("%s", word);
            search(word);
        } else if(strcmp(option, "MARK") == 0) {
            scanf("%s", word);
            mark(word);
        } else if(strcmp(option, "ALPHANUM_LIST") == 0) {
            alphanum_list();
        } else if(strcmp(option, "MARK_LIST") == 0) {
            mark_list();
        }
    }

    return 0;
}

struct node* search(char *word)
{
    struct node *current=root;

    while(strcmp(current->word, word) != 0) {
        if(current != NULL) {
            if(strcmp(current->word,word) < 0) {
                current = current->leftChild;
            } else {
                current = current->rightChild;
            }

            if(current == NULL) {
                printf("WORD DOESN'T EXIST\n");
                return NULL;
            }
        }
    }

    printf("%s %s\n", current->word, current->translation);
    return current;
}

这里定义了树的操作。

struct node* load()
{
    char str[1000];
    char word[MAXP];
    char translation[MAXT];

    while(1) {
        do {
            gets(str);
            sscanf("%s %s", word, translation);
            loader(word, translation);
        } while(strcmp(str,"end$dictionary") != 0);
        printf("DICTIONARY LOADED\n");
    }
}

1 个答案:

答案 0 :(得分:1)

loader函数不会复制插入字典节点中的单词...它们都会指向load函数中的本地数组,只要load函数就会失效1}}函数返回。以这种方式修复代码:

tempNode->word = strdup(word);
tempNode->translation = strdup(translation);
tempNode->leftChild = NULL;
tempNode->rightChild = NULL;

当字典为空时,将新节点存储到root,但您应该从该函数返回。然后,当前代码调用未定义的行为,因为current未初始化。

以下是简化版本:

void loader(const char *word, const char *translation) {
    struct node *tempNode = malloc(sizeof(*tempNode));
    struct node *current;

    if (tempNode == NULL) {
        fprintf(stderr, "cannot allocate memory\n");
        return;
    }
    tempNode->word = strdup(word);
    tempNode->translation = strdup(translation);
    tempNode->leftChild = tempNode->rightChild = NULL;

    /* If tree is empty */
    if (root == NULL) {
        root = tempNode;
        return;
    }
    for (current = root;;) {
       /* Goes to the left side of the tree */
        int cmp = strcmp(word, current->word);
        if (cmp == 0) {
            fprintf(stderr, "duplicate word: %s\n", word);
            free(tempNode->word);
            free(tempNode->translation);
            free(tempNode);
            return;
        }
        if (cmp < 0) {
            if (current->leftChild == NULL) {
                current->leftChild = tempNode;
                return;
            }
            current = current->leftChild;
        } else {
            if (current->rightChild == NULL) {
                current->rightChild = tempNode;
                return;
            }
            current = current->rightChild;
        }
    }
}

您的搜索功能在空字典上崩溃,因为current == NULL上的测试在取消引用指针后完成。顺便说一句,树的行走方向错误。

以下是更正后的版本:

struct node *search(const char *word) {
    struct node *current = root;

    while (current) {
        int cmp = strcmp(word, current->word);
        if (cmp == 0) {
            printf("%s %s\n", current->word, current->translation);
            return current;
        }
        if (cmp < 0) {
            current = current->leftChild;
        } else {
            current = current->rightChild;
        }
    }
    printf("WORD DOESN'T EXIST: %s\n", word);
    return NULL;
}