簡體   English   中英

在C中將int與NULL比較-本教程是否正確?

[英]Comparing int to NULL in C - is this tutorial incorrect?

我正在看本教程http://www.learn-c.org/en/Binary_trees ,在insert函數中它將int與NULL比較。 它在tut網站上似乎運行良好,但對我而言不起作用,而我的研究表明它不起作用。 我的代碼如下。

  1. 我在這里錯了還是本教程錯了嗎?
  2. 如果教程有誤,是否有任何方法可以動態設置BST第一個節點的值? 我考慮過檢查left和right是否均為空,但這只會繼續重置第一個節點。 為節點的值設置第三個指針似乎很浪費,但也許這是唯一的方法?

     #include <stdio.h> #include <malloc.h> struct bstNode { int val; struct bstNode *left; struct bstNode *right; }; int insert(struct bstNode *head, int val); void printDFS(struct bstNode *head); int main() { struct bstNode *bstTree = malloc(sizeof(struct bstNode)); insert(bstTree, 8); insert(bstTree, 5); insert(bstTree, 98); insert(bstTree, 2); insert(bstTree, 15); insert(bstTree, 65); insert(bstTree, 15); printDFS(bstTree); } int insert(struct bstNode *head, int val) { //This is the problem statement, it contains random data when I debug as it's uninitialized if (head->val == NULL) { head->val = val; return 0; } if (val < head->val) { if (head->left != NULL) { return insert(head->left, val); } else { head->left = malloc(sizeof(struct bstNode)); head->left->val = val; return 0; } } else { if (head->right != NULL) { return insert(head->right, val); } else { head->right = malloc(sizeof(struct bstNode)); head->right->val = val; return 0; } } } void printDFS(struct bstNode *head) { if (head->left != NULL) printDFS(head->left); printf("%d ", head->val); if (head->right != NULL) printDFS(head->right); } 

本教程不正確。 它有兩個無效的假設。

  1. 它假定NULL等於0。雖然在大多數情況下,它定義為(void *)0 ,但不一定總是這樣。 它還在期望int位置使用了指針,因此對指針表示形式有依賴性。
  2. 假定初始節點的val 0。 當使用malloc分配malloc ,不會初始化內存(如您所知)。

該代碼還通過假定0不是要插入到列表中的有效值來起作用,因為它使用0作為標記值來表示一個空列表。

在假定將0用作前哨的情況下,可以按以下方式固定代碼。

首先,在創建初始節點時,請使用calloc而不是malloc calloc函數會將所有字節初始化為0。這將為您提供一個初始成員,其中val設置為0,而leftright設置為NULL

另外,如果它們失敗,則應始終檢查malloccallocrealloc的返回值。

int main() {
    struct bstNode *bstTree = calloc(1, sizeof(struct bstNode));
    if (bstTree == NULL) {
        perror("calloc failed");
        exit(1);
    }

其次,通過將NULL替換為0來擺脫整數/指針比較。

    if (head->val == 0) {

做到這兩點應該會使代碼正常工作。

退后一步,放眼大局,這里存在一些設計問題。

insert函數返回一個int ,但是從不使用返回值。 實際上,此函數只能返回0。最好將返回類型更改為void

讓一個空樹包含一個帶有前哨值的節點會限制您可以輸入的值。通過使頭節點為NULL指針來使之成為空樹更好。 這可以在插入函數中通過傳遞頭指針的地址來解決,因此如果列表為空,則可以對其進行修改:

void insert(struct bstNode **head, int val) {
    if (*head == NULL) {
        *head = malloc(sizeof(struct bstNode));
        if (*head == NULL) {
            perror("malloc failed");
            exit(1);
        }
        (*head)->val = val;
        (*head)->left = NULL;
        (*head)->right = NULL;
        return;
    }

    if (val < (*head)->val) {
    ...

然后,您可以這樣稱呼它:

struct bstNode *bstTree = NULL;
insert(&bstTree, 8);
...
if (head->val == NULL) {
    head->val = val;
    return 0;
}

我認為tuto要檢查val是否為NULL,因為insert返回一個int值。 您應該將插入函數替換為以下內容:

struct bstNode *new_bstNode(int val, struct bstNode *left, struct bstNode *right)
{
    struct bstNode *elem = malloc(sizeof(*elem));
    if (elem == NULL)
        return NULL;
    elem->val = val;
    elem->left = left;
    elem->right = right;
    return elem;
}

struct bstNode *insert(struct bstNode *head, int val) {
    if (head == NULL)
        return new_bstNode(val, NULL, NULL);

    if (val < head->val) {
        if (head->left != NULL)
            return insert(head->left, val);
        else
            return head->left = new_bstNode(val, NULL, NULL);
    } else {
        if (head->right != NULL)
            return insert(head->right, val);
        else
            return head->right = new_bstNode(val, NULL, NULL);
    }
}

所以您的主要需要替換為

int main() {
    struct bstNode *bstTree = insert(bstTree, 8);
    insert(bstTree, 5);
    insert(bstTree, 98);
    insert(bstTree, 2);
    insert(bstTree, 15);
    insert(bstTree, 65);
    insert(bstTree, 15);
    printDFS(bstTree);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM