【问题标题】:Building a Huffman tree from a binary search tree从二叉搜索树构建霍夫曼树
【发布时间】:2025-11-25 13:50:01
【问题描述】:

我正在尝试用二叉搜索树构建一棵霍夫曼树。可悲的是我的代码崩溃了(分段错误(核心转储))。

struct 是这样定义的:

struct Node
{
  unsigned char m_ch;
  int m_freq;
  struct Node *m_ls,*m_rs;
  struct Node *m_hls,*m_hrs;
};

delMin 被传递一个指向二叉搜索树的双指针,并从中删除最左边的叶子,除非它到达带有m_ch==0 的节点并返回删除的节点

我找不到我的错误

struct Node *delMin(struct Node **root)
{
    struct Node *current = *root;
    struct Node *b4Current;

    if (current == NULL)
        return NULL;

    while (current->m_ls != NULL)
    {
        if (current->m_ch == 0)
            break;

        b4Current = current;
        current = current->m_ls;
    }

    if (current->m_ch == 0)
        b4Current->m_ls = NULL;
    else
    {
        if (b4Current == NULL)
            *root = current->m_rs;
        else
            b4Current->m_ls = current->m_rs;
    }

    return current;
}


struct Node *huffman(struct Node *root)
{
    struct Node *left;
    struct Node *right;
    struct Node *tempRoot;
    struct Node *huffmanTree;

    while (root->m_ch != 0)
    {
        left = delMin(&root);
        right = delMin(&root);
        tempRoot = createNode((left->m_freq) + (right->m_freq), 0);
        tempRoot->m_hls = left;
        tempRoot->m_hrs = right;
        insertTree(&root, tempRoot);
    }

    huffmanTree = tempRoot;
    return huffmanTree;
}

编辑:为Huffman 调用的insertTree 函数添加了代码

void insertTree(struct Node **root,struct Node *n)
{
  if (!*root)
  {
    *root=n;
    return;
  }
  if(n->m_freq<(*root)->m_freq)
  {
    insertTree(&((*root)->m_ls),n);
  }
  else
  {
    insertTree(&((*root)->m_rs),n);
  }
}

【问题讨论】:

  • 使用调试器或插入puts() 调用来确定发生故障的确切位置。然后跟踪关联的逻辑,找出问题所在。
  • 可能违反分段的候选者是while (root-&gt;m_ch) ...:从树中删除最后一个节点后,rootNULL,您不能使用-&gt; 取消引用它。所以while (root) 应该没问题。
  • 如果root 是一个满足current-&gt;m_ls != NULLcurrent-&gt;m_ch==0 的节点,则delMin() 的while 循环立即退出。由于current-&gt;m_ch==0,进入测试并执行b4Current-&gt;m_ls=NULL;。但是b4Current 没有初始化:可以触发分段错误。
  • while (root) 启动一个 inf 循环 @MOehm
  • 好的,我看到您通过插入带有m_ch == 0 的虚拟节点使事情变得过于复杂。但是你没有展示你是如何构建二叉树的。

标签: c binary-tree binary-search-tree huffman-code


【解决方案1】:

delMin这个代码部分

if (current->m_ch == 0)
    b4Current->m_ls = NULL;
else
{
    if (b4Current == NULL)
        *root = current->m_rs;
    else
        b4Current->m_ls = current->m_rs;
}

不保证b4Current 不为NULL。

考虑根节点有m_ch == 0m_ls == NULL 的情况。您将使用if 分支并取消引用b4Current

您需要使用NULL 初始化b4Current,并在取消引用之前对其进行检查。

delMin 中初始化current = *root 或在huffman 中取消引用之前,您还需要确保root 本身不为空

这些都应该初始化为NULL

struct Node *left;
struct Node *right;
struct Node *tempRoot;
struct Node *huffmanTree;

同样,有可能永远不会进入 while 循环,使 tempRoot 未设置,从而在您返回其值时在 huffman 的调用者中导致潜在的 segFault。

【讨论】:

  • 我仍然得到你的 seggestions 的 sefFault
  • 有没有可能出现在 InsertTree 中,而你没有向我们展示?
  • 我已将其添加到您的帖子中。我怀疑其他(仍然缺少)代码中存在段错误的机会,但是您向我们展示的内容表明您需要仔细查看所有指针处理。