C语言BST代码在Linux/WSL2正常但Windows下出错求助
BST代码在Windows下运行异常的原因及修复
核心问题:未初始化的局部指针
你的代码在Windows下运行异常的直接原因是**main函数中root指针未初始化**。C语言中,局部变量若未显式初始化,其值为未定义的垃圾值:
- Linux/WSL2环境下,栈内存可能恰好被初始化为NULL,符合BST插入的预期逻辑;
- Windows环境下,
root被赋予了垃圾值(你调试发现是1),导致第一次调用insert_in_bst时,!root条件不成立,直接进入分支处理,破坏了BST的构建逻辑。
此外还有两个次要问题:
delete_in_bst函数返回更新后的根节点,但main中未接收返回值,导致删除操作后根节点指针未更新;levelwise函数中存在内存泄漏,且queue通过malloc分配后未初始化成员,可能引发异常。
修复后的完整代码
以下是修复所有问题后的代码,关键修改处已用注释标注:
#include <stdio.h> #include <malloc.h> typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; typedef struct node { TreeNode *data; struct node *next; } node; typedef struct queue { node *head; node *tail; int size; } queue; TreeNode *insert_in_bst(int element, TreeNode *root); TreeNode *delete_in_bst(int element, TreeNode *root); void inorder(TreeNode *root); void levelwise(TreeNode *root); void enqueue(queue *q, TreeNode *root); node *dequeue(queue *q); void mirror_image(TreeNode *root); int height(TreeNode *root); int main(int argc, char *argv[]) { int n = 0; printf("Enter elements to be added to bst - "); scanf("%d", &n); TreeNode *root = NULL; // 修复:显式初始化为NULL while (n != -1) { root = insert_in_bst(n, root); scanf("%d", &n); } levelwise(root); printf("\nCurrent inorder - "); inorder(root); int del; printf("\nEnter element to delete - "); scanf("%d", &del); root = delete_in_bst(del, root); // 修复:接收删除后的新根节点 levelwise(root); printf("\nNew inorder - "); inorder(root); printf("\nMirror image\n"); mirror_image(root); levelwise(root); int h = height(root); printf("\nHeight = %d", h); return 0; } TreeNode *insert_in_bst(int element, TreeNode *root) { if (!root) { TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode)); newNode->data = element; newNode->left = NULL; // 修复:新节点左右指针显式初始化为NULL newNode->right = NULL; return newNode; } if (element < root->data) { root->left = insert_in_bst(element, root->left); } else { root->right = insert_in_bst(element, root->right); } return root; } TreeNode *delete_in_bst(int element, TreeNode *root) { if (!root) return NULL; if (element < root->data) { root->left = delete_in_bst(element, root->left); } else if (element > root->data) { root->right = delete_in_bst(element, root->right); } else { if (!root->left) return root->right; else if (!root->right) return root->left; else { TreeNode *curr = root->right; while (curr->left) // 修复:条件应为curr->left不为空,原逻辑写反了 curr = curr->left; root->data = curr->data; root->right = delete_in_bst(curr->data, root->right); } } return root; } void inorder(TreeNode *root) { if (!root) return; inorder(root->left); printf("%d ", root->data); inorder(root->right); } void levelwise(TreeNode *root) { if (!root) return; // 修复:空树直接返回,避免后续操作出错 queue *q = (queue *)malloc(sizeof(queue)); q->head = NULL; q->tail = NULL; q->size = 0; // 修复:显式初始化队列成员 enqueue(q, root); while (q->size != 0) { int l = q->size; for (int i = 0; i < l; i++) { node *temp = dequeue(q); TreeNode *t = temp->data; printf("%d ", t->data); free(temp); // 修复:释放dequeue出来的节点,避免内存泄漏 if (t->left) { enqueue(q, t->left); } if (t->right) { enqueue(q, t->right); } } printf("\n"); } free(q); // 修复:释放队列结构,避免内存泄漏 } void enqueue(queue *q, TreeNode *root) { node *temp = (node *)malloc(sizeof(node)); temp->data = root; temp->next = NULL; // 修复:新节点next指针初始化为NULL if (!q->head) { q->head = temp; q->tail = temp; q->size = 1; } else { q->tail->next = temp; q->tail = q->tail->next; q->size++; } } node *dequeue(queue *q) { node *top = q->head; q->head = q->head->next; if (!q->head) q->tail = NULL; // 修复:队列空时tail置为NULL q->size--; return top; } void mirror_image(TreeNode *root) { if (!root) return; TreeNode *temp = root->left; root->left = root->right; root->right = temp; mirror_image(root->left); mirror_image(root->right); } int height(TreeNode *root) { if (!root) return 0; int lh = height(root->left); int rh = height(root->right); return 1 + (lh > rh ? lh : rh); }
关键修复点说明
root指针初始化:TreeNode *root = NULL;,确保第一次插入时从空树开始构建;- 删除操作接收返回值:
root = delete_in_bst(del, root);,更新根节点指针; - 新节点指针初始化:
newNode->left = NULL; newNode->right = NULL;,避免垃圾值影响; - 删除逻辑的循环条件修正:原
while (!curr->left)会导致无限循环,改为while (curr->left); - 队列初始化与内存泄漏修复:显式初始化队列成员,释放
dequeue的节点和队列结构,避免内存泄漏; - 空树判断:
levelwise开头增加if (!root) return;,避免空树时的非法操作。
内容的提问来源于stack exchange,提问作者Soham Ratnaparkhi
相关产品推荐
相关产品推荐

