二叉搜索树C实现

Pas*_*ian 5 c binary-search-tree

我最近编写了一段相当简单的代码,试图用C语言实现二进制搜索树,包括插入,搜索,删除和显示操作.不幸的是,代码似乎不起作用.

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

struct TreeNode {
    int data;
    struct TreeNode *leftChildNode;
    struct TreeNode *rightChildNode;
};

typedef struct TreeNode node;
node *rootNode = NULL;

void insertNode(int i, node *n) {
    if(n == NULL) {
        n = (node*)malloc(sizeof(node));
        n->leftChildNode = NULL;
        n->rightChildNode = NULL;
        n->data = i;
    }
    else 
    if(n->data == i)
        printf("\nThis value already exists in the tree!");
    else
    if(i > n->data)
        insertNode(i, n->rightChildNode);
    else
        insertNode(i, n->leftChildNode);
    }

void searchNode(int i, node *n) {
    if(n == NULL)
        printf("\nValue does not exist in tree!");
    else
    if(n->data == i)
        printf("\nValue found!");
    else
    if(i > n->data)
        searchNode(i, n->rightChildNode);
    else
        searchNode(i, n->leftChildNode);
    }

void deleteNode(int i, node *n) {
    if(n == NULL)
        printf("\nValue does not exist in tree!");
    else
    if(n->data == i) {
        if(n->leftChildNode == NULL)
            n = n->rightChildNode;
        else
        if(n->rightChildNode == NULL)
            n = n->leftChildNode;
        else {
            node *temp = n->rightChildNode;
            while(temp->leftChildNode != NULL)
                temp = temp->leftChildNode;
            n = temp;
        }
    }
    else
    if(i > n->data)
        deleteNode(i, n->rightChildNode);
    else
        deleteNode(i, n->leftChildNode);
    }

void displayPreOrder(node *n) {
    if(n != NULL) {
        printf("%d ", n->data);
        displayPreOrder(n->leftChildNode);
        displayPreOrder(n->rightChildNode);
    }
}

void displayPostOrder(node *n) {
    if(n != NULL) {
        displayPostOrder(n->leftChildNode);
        displayPostOrder(n->rightChildNode);
        printf("%d ", n->data);
    }
}

void displayInOrder(node *n) {
    if(n != NULL) {
        displayInOrder(n->leftChildNode);
        printf("%d ", n->data);
        displayInOrder(n->rightChildNode);
    }
}

int main(void) {
    int ch, num, num1;
    do {
        printf("\nSelect a choice from the menu below.");
        printf("\n1. Insert a node.");
        printf("\n2. Search for a node.");
        printf("\n3. Delete a node.");
        printf("\n4. Display the Binary Search Tree.");
        printf("\nChoice: ");
        scanf("%d", &ch);
        switch(ch) {
            case 1: printf("\nEnter an element: ");
                    scanf("%d", &num);
                    //printf("YESYES");
                    insertNode(num, rootNode);
                    break;

            case 2: printf("\nEnter the element to be searched for: ");
                    scanf("%d", &num);
                    searchNode(num, rootNode);
                    break;

            case 3: printf("\nEnter the element to be deleted: ");
                    scanf("%d", &num);
                    deleteNode(num, rootNode);
                    break;

            case 4: printf("\nSelect an order for the elements to be display in.");
                    printf("\n1. Pre-order.");
                    printf("\n2. Post-order.");
                    printf("\n3. In-order.");
                    printf("\nChoice: ");
                    scanf("%d", &num1);
                    switch(num1) {
                        case 1: printf("\nPre-order Display: ");
                                displayPreOrder(rootNode);
                                break;

                        case 2: printf("\nPost-order Display: ");
                                displayPostOrder(rootNode);
                                break;

                        case 3: printf("\nIn-order Display: ");
                                displayInOrder(rootNode);
                                break;

                        default: exit(0);
                    }
                    break;

            default: exit(0);
            }
        //printf("%d", rootNode->data);
        printf("\nIf you want to return to the menu, press 1.");
        printf("\nChoice: ");
        scanf("%d", &num);
    } while(num == 1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

实际上,请注意printf("%d", rootNode->data);do-whilemain()结尾之前的注释行.如果我取消注释这一行,编译程序并运行它,程序会抛出一个分段错误.任何人都可以告诉我为什么会出现这个错误以及为什么整个代码没有运行?提前致谢.

Mat*_*ert 5

你对C处理参数的方式有误解.在C中,所有参数都按值传递,包括指针.当您在函数内重新分配指针时,您将重新分配该指针的副本.

例如:

void f ( int *p );

int *p;

f(p);
Run Code Online (Sandbox Code Playgroud)

&p指针的地址()在函数中是不同的.它们都指向相同的位置(具有相同的值),但每个都有不同的地址.将指针指定给返回值时malloc,它只分配该指针的函数本地副本.

解决这个问题的一种方法是引入另一个间接层,并传递指针的地址:void insertNode(int i, node **n),你可以调用它insertNode(0, &n).当你想把它改成别的东西时,取消引用它然后分配:*p = malloc(sizeof(node)).

另一种解决方案是让函数返回指针并将其分配给调用代码:return malloc(sizeof(node)).(注意:您实际上会在初始化代码之后返回它...也不会malloc在C中转换返回值).


Vic*_*and 1

在顶部,您声明

node *rootNode = NULL; 
Run Code Online (Sandbox Code Playgroud)

如果你没有运行insertNode(成功 - 请参阅 Matt 的答案),则在尝试打印节点时该节点仍将为 NULL,这就是你收到段错误的原因。