[英]Comparing int to NULL in C - is this tutorial incorrect?
我正在看本教程http://www.learn-c.org/en/Binary_trees ,在insert函數中它將int與NULL比較。 它在tut網站上似乎運行良好,但對我而言不起作用,而我的研究表明它不起作用。 我的代碼如下。
如果教程有誤,是否有任何方法可以動態設置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); }
本教程不正確。 它有兩個無效的假設。
NULL
等於0。雖然在大多數情況下,它定義為(void *)0
,但不一定總是這樣。 它還在期望int
位置使用了指針,因此對指針表示形式有依賴性。 val
0。 當使用malloc
分配malloc
,不會初始化內存(如您所知)。 該代碼還通過假定0不是要插入到列表中的有效值來起作用,因為它使用0作為標記值來表示一個空列表。
在假定將0用作前哨的情況下,可以按以下方式固定代碼。
首先,在創建初始節點時,請使用calloc
而不是malloc
。 calloc
函數會將所有字節初始化為0。這將為您提供一個初始成員,其中val
設置為0,而left
和right
設置為NULL
。
另外,如果它們失敗,則應始終檢查malloc
, calloc
和realloc
的返回值。
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.