You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现AVL树插入操作?C语言AVL插入代码运行无输出排查

AVL树插入代码问题修复方案

核心问题定位

你的代码无输出是因为触发了空指针非法访问导致程序崩溃,再加上根节点更新逻辑错误,共有两个核心问题:

  • 问题1:未调用已封装的Height()函数,直接访问空节点的Height成员触发段错误
    你已经实现了Height()函数处理空节点返回-1的逻辑,但在旋转函数、插入函数更新高度、判断平衡因子的位置,全部直接访问左/右子树->Height,当子树为NULL时就会非法访问内存,程序直接退出无输出。
  • 问题2:main函数中Insert返回值丢失
    AVL插入会因为旋转改变根节点地址,除了第一次插入,后续所有Insert调用都没有将返回的新根赋值给Tree变量,导致Tree始终指向旧根,树结构完全错乱。

修复要点

  1. 所有需要获取节点高度的位置,统一调用Height(节点指针),不要直接访问->Height成员
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 20:36:05