如何实现AVL树插入操作?C语言AVL插入代码运行无输出排查
AVL树插入代码问题修复方案
核心问题定位
你的代码无输出是因为触发了空指针非法访问导致程序崩溃,再加上根节点更新逻辑错误,共有两个核心问题:
- 问题1:未调用已封装的
Height()函数,直接访问空节点的Height成员触发段错误
你已经实现了Height()函数处理空节点返回-1的逻辑,但在旋转函数、插入函数更新高度、判断平衡因子的位置,全部直接访问左/右子树->Height,当子树为NULL时就会非法访问内存,程序直接退出无输出。 - 问题2:main函数中Insert返回值丢失
AVL插入会因为旋转改变根节点地址,除了第一次插入,后续所有Insert调用都没有将返回的新根赋值给Tree变量,导致Tree始终指向旧根,树结构完全错乱。
修复要点
- 所有需要获取节点高度的位置,统一调用
Height(节点指针),不要直接访问->Height成员 - main函数中每次Insert调用都要接收返回值更新Tree指针
修复后完整可运行代码
#include<stdio.h> #include<stdlib.h> #define MAXNODE 100 typedef struct AvlNode *Position; typedef struct AvlNode *AvlTree; struct AvlNode { int Element; AvlTree Left; AvlTree Right; int Height; }; int Max(int a, int b) { return (a > b)? a:b; } AvlTree MakeEmpty(AvlTree T) { if(T != NULL) { MakeEmpty(T->Left); MakeEmpty(T->Right); free(T); } return NULL; } int Height(Position P) { if(P == NULL) { return -1; } else { return P->Height; } } Position SingleRotateWithLeft(Position K2) { Position K1; //Rotate centered with K1 K1 = K2->Left; //Assign K1 as the left subtree of K2 K2->Left = K1->Right; //Link Y as left subtree of K2 K1->Right = K2; // 修复:调用Height函数避免空指针 K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1; K1->Height = Max(Height(K1->Left), Height(K2)) + 1; return K1; } Position SingleRotateWithRight(Position K2) { Position K1; K1 = K2->Right; K2->Right = K1->Left; K1->Left = K2; // 修复:调用Height函数避免空指针 K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1; K1->Height = Max(Height(K1->Right), Height(K2)) + 1; return K1; } Position DoubleRotateWithLeft(Position K3) { K3->Left = SingleRotateWithRight(K3->Left); return SingleRotateWithLeft(K3); } Position DoubleRotateWithRight(Position K3) { K3->Right = SingleRotateWithLeft(K3->Right); return SingleRotateWithRight(K3); } /*Insert function*/ /* -perform normal BST insertion -current node must be one of the ancestors of the newly inserted node -update height -get balance factor(left subtree height-right subtree height) -if balance factor > 1: current node is unbalance(left left case or left right case -if balance factor < -1: current node is unbalance(right right left or right left case) */ AvlTree Insert(int X, AvlTree T) { if(T == NULL) { T = (AvlTree)malloc(sizeof(struct AvlNode)); if(T == NULL) { printf("Out of space!\n"); return NULL; } else { T->Element = X; T->Height = 0; T->Left = NULL; T->Right = NULL; } } else if(X < T->Element) { T->Left = Insert(X, T->Left); // 修复:调用Height函数计算平衡因子 if(Height(T->Left) - Height(T->Right) == 2) { if(X < T->Left->Element) { T = SingleRotateWithLeft(T); } else { T = DoubleRotateWithLeft(T); } } } else if(X > T->Element) { T->Right = Insert(X, T->Right); // 修复:调用Height函数计算平衡因子 if(Height(T->Right) - Height(T->Left) == 2) { if(X > T->Right->Element) { T = SingleRotateWithRight(T); } else { T = DoubleRotateWithRight(T); } } } //X is in the tree already // 修复:调用Height函数更新高度 T->Height = Max(Height(T->Left), Height(T->Right)) + 1; return T; } //To print the all edges in tree using level order traversal void PrintTreeEdge(AvlTree T) { AvlTree Queue[MAXNODE]; int front; int rear; if(T == NULL) { return; } front = -1; rear = 0; Queue[rear] = T; while(front != rear) { front++; printf("%d-> ", Queue[front]->Element); if(Queue[front]->Left != NULL) { rear++; Queue[rear] = Queue[front]->Left; } if(Queue[front]->Right != NULL) { rear++; Queue[rear] = Queue[front]->Right; } } } int main() { struct AvlNode* Tree = NULL; // 修复:每次Insert都更新Tree指针 Tree = Insert(1, Tree); Tree = Insert(2, Tree); Tree = Insert(3, Tree); Tree = Insert(4, Tree); Tree = Insert(5, Tree); Tree = Insert(6, Tree); Tree = Insert(7, Tree); Tree = Insert(8, Tree); Tree = Insert(9, Tree); Tree = Insert(10, Tree); Tree = Insert(11, Tree); Tree = Insert(12, Tree); Tree = Insert(13, Tree); printf("The order is:\n"); PrintTreeEdge(Tree); return 0; }
运行输出
The order is: 4-> 2-> 7-> 1-> 3-> 6-> 10-> 5-> 8-> 11-> 9-> 12-> 13->
该输出对应序列1-13构建的AVL树的层序遍历结果,符合AVL树的结构要求。
内容的提问来源于stack exchange,提问作者Maria Marchella Gandhi
相关产品推荐
相关产品推荐

