【问题标题】:C implementation of skew heap斜堆的C实现
【发布时间】:2012-11-01 10:35:41
【问题描述】:

我正在尝试在 C 中实现倾斜堆,但我的代码无法编译。我在 C 语言方面没有那么有经验,也从未在 C 语言中创建过任何类型的堆。这就是为什么我不知道如何解决它,我希望有人能指出我正确的方向。我一直在阅读有关倾斜堆的文章,这是我迄今为止使用我在网上找到的算法得到的。提前致谢。

typedef struct node
{
int value;
struct node * root;
struct node * leftchild;
struct node * rightchild;
} Node;

struct skewHeap
{
    struct node * root;
};

void skewHeapInit (struct skewHeap * sk)
{
    sk->root = 0;
}

void skewHeapAdd (struct skewHeap *sk)
{
    struct node *n = (struct node *) malloc(sizeof(struct node));
    assert(n != 0);
    n->value = 0;
    n->leftchild = 0;
    n->rightchild = 0;
    line 185. s->root = skewHeapMerge(s->root, n);
}

void skewHeapRemoveFirst (struct skewHeap *sk)
{
    struct node * n = sk->root;
    free(n);
    sk->root = skewHeapMerge(n->leftchild, n->rightchild);
}

line 196. struct node * skewHeapMerge(struct node *left, struct node *right)
{
    struct node *temp = (struct node *) malloc(sizeof(struct node));

    if (left == NULL) 
        return *right;

    if (right == NULL) 
        return *left;

    if (left->value < right-> value)
    {
        temp = left->leftchild;
        left->leftchild = skewHeapMerge(left->rightchild, right);
        left->rightchild = temp;
        return left;
    }
    else
    {
        temp = right->rightchild;
        right->rightchild = skewHeapMerge(right->leftchild, left);
        right->leftchild = temp;
        return right;
    }
}

这些是我目前遇到的编译错误:

program.c: In function ‘skewHeapAdd’:
program.c:185: warning: implicit declaration of function ‘skewHeapMerge’
program.c:185: warning: assignment makes pointer from integer without a cast
program.c: In function ‘skewHeapRemoveFirst’:
program.c:191: warning: assignment makes pointer from integer without a cast
program.c: At top level:
program.c:196: error: conflicting types for ‘skewHeapMerge’
program.c:185: note: previous implicit declaration of ‘skewHeapMerge’ was here
program.c: In function ‘skewHeapMerge’:
program.c:202: error: incompatible types when returning type ‘struct node’ but ‘struct   node *’ was expected
program.c:205: error: incompatible types when returning type ‘struct node’ but ‘struct node *’ was expected

【问题讨论】:

  • 编译错误是什么?
  • 看起来您已经编写了一个完整的程序,然后编译并不知所措。试着养成编写一点代码并编译它的习惯。结合阅读编译器错误消息所说的内容。您应该始终从 first 错误消息开始,因为它可能会导致其他令人困惑的错误消息。
  • 有点乱!您将在合并中耗尽内存,您的 temp 不需要分配内存,您只是使用它来指向现有内存。您还没有显示“节点”的定义
  • 与编译器错误无关,但您的函数 skewHeapRemoveFirst 在错误的时间释放了 nn 被释放后就不能使用了。
  • 感谢快速 cmets 的家伙。这是我的节点定义:'typedef struct node { int value;结构节点 * 左孩子;结构节点 * 右子节点; } 节点;'

标签: c heap skew


【解决方案1】:

关于编译器错误,

program.c: In function ‘skewHeapAdd’:
program.c:185: warning: implicit declaration of function ‘skewHeapMerge’
program.c:185: warning: assignment makes pointer from integer without a cast

告诉你 skewHeapMerge 的原型不在定义 skewHeapAdd 的范围内,因此(编译器显然在 C89 模式下运行,但幸运的是警告它),编译器假设返回类型为 @987654324 的隐式声明@ 代表skewHeapMerge

为所有函数添加一个带有原型的头文件,并在所有使用或定义这些函数的*.c 文件中添加#include,以便编译器知道函数的类型。

program.c: In function ‘skewHeapRemoveFirst’:
program.c:191: warning: assignment makes pointer from integer without a cast

应该是那一行

sk->root = skewHeapMerge(n->leftchild, n->rightchild);

其中sk-&gt;rootstruct node*,但由于skewHeapMerge 的隐式声明,假定返回int

program.c: At top level:
program.c:196: error: conflicting types for ‘skewHeapMerge’
program.c:185: note: previous implicit declaration of ‘skewHeapMerge’ was here

这里编译器发现skewHeapMerge 的定义给出的类型与隐式声明中的类型冲突。

program.c: In function ‘skewHeapMerge’:
program.c:202: error: incompatible types when returning type ‘struct node’ but ‘struct   node *’ was expected
program.c:205: error: incompatible types when returning type ‘struct node’ but ‘struct node *’ was expected

那是为了线条

if (left == NULL) 
    return *right;

if (right == NULL) 
    return *left;

你应该在哪里返回right resp。 left 而不是 *right resp。 *left(一开始我忽略了)。


skewHeapRemoveFirst你写错了

void skewHeapRemoveFirst (struct skewHeap *sk)
{
    struct node * n = sk->root;
    free(n);
    sk->root = skewHeapMerge(n->leftchild, n->rightchild);
}

你在freed 之后使用n。您必须交换该函数中的最后两行。

skewHeapMerge

struct node * skewHeapMerge(struct node *left, struct node *right)
{
    struct node *temp = (struct node *) malloc(sizeof(struct node));

    if (left == NULL)
        return *right;

    if (right == NULL)
        return *left;

您正在泄漏内存。删除分配,因为如果完全使用了temp,您可以将left-&gt;leftchildright-&gt;rightchild 分配给它。

【讨论】:

  • 更新了编译器消息的讨论。
  • 谢谢你的解释,让它编译没有错误。
猜你喜欢
  • 2013-11-19
  • 2010-11-27
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 2015-03-17
  • 2020-09-13
相关资源
最近更新 更多