【问题标题】:Creating a push() method for a singly linked list with two parameters为具有两个参数的单链表创建 push() 方法
【发布时间】:2014-02-10 00:01:55
【问题描述】:

我需要为将元素压入堆栈的程序创建 push 方法。我创建了这个typedef

typedef struct node{
    int value;
    struct node *next;
} Node;

在我的 main 中使用这段 sn-p 代码:

Node *stackptr;
stackptr = NULL;

这是我遇到问题的地方,我不确定到底发生了什么 - 在我的推送方法中,我不确定我是否将更新后的指针返回到堆栈顶部。我想检查它是否也是空的,但我会到最后。这是 push() 函数:

void push(Node *stkptr, int i){
   Node *temp;
   temp = malloc(sizeof(Node));
   temp->value = i;
   temp->next = *stkptr;
   return *stkptr = temp;
}

希望这对我想要表达的内容有某种意义。感谢您能给我的任何建议。希望一切都好。

最后我需要修复我的 int pop() 函数!我必须返回弹出的节点的值。我相信我快到了 - 我的编译器仍在抛出错误。这是我目前所拥有的:

int pop(Node** stkptr){
Node *temp;
temp = malloc(sizeof(Node));

if((*stkptr) == NULL){
    fprintf(stderr, "The stack is empty. Pop is not allowed\n");
    return 0;
}
else{
    temp = *stkptr;
    stkptr = *temp;
}
return stkptr;
free(temp);
}

但是,编译器抛出错误: 从“Node”类型分配给“struct Node **”类型时的类型不兼容

警告:return 从没有强制转换的指针中生成整数

谁能帮我解决我的问题!谢谢!

【问题讨论】:

  • *stkptr 的类型是 Node,不是 Node*
  • 您不能从定义为返回 void 的函数中返回值。
  • @JonathanLeffler 你能看看我的编辑吗 - 我添加了一个关于 pop() 的问题。再次感谢您的所有帮助。

标签: c stack push


【解决方案1】:

这肯定有很多重复项(例如,来自相关问题部分的Implementing stack with linked list in C),但基本上,您需要将指向指针的指针传递给函数:

void push(Node **stkptr, int i)
{
    Node *temp;
    temp = malloc(sizeof(Node));
    temp->value = i;
    temp->next = *stkptr;
    *stkptr = temp;
}

您也不能从返回void 的函数中返回值。您还应该检查内存分配是否有效。

例如,您可以从您的主程序中调用它:

Node *stack = NULL;
int i;

while (get_an_integer(&i) != EOF)
    push(&stack, i);

其中get_an_integer() 是一个假设函数,它从某处读取一个整数并将其分配给i,同时返回一个状态(0 - 得到一个整数;EOF - 没有得到一个整数)。

另一种设计从函数返回新的栈头:

Node *push(Node *stkptr, int i)
{
    Node *node;
    node = malloc(sizeof(Node));
    node->value = i;
    node->next = stkptr;
    return node;
}

有调用顺序:

Node *stack = NULL;
int i;

while (get_an_integer(&i) != EOF)
    stack = push(stack, i);

关于pop()的问题

pop() 函数似乎是删除和销毁堆栈上的第一项,而不是返回它。但是,它存在许多缺陷,例如它分配空间,然后用堆栈中的信息覆盖指针,然后在释放数据之前返回。所以,假设需要拆除作业,代码应该是:

int pop(Node **stkptr)
{
    assert(stkptr != 0);
    Node *temp = *stkptr;

    if (temp == NULL)
    {
        fprintf(stderr, "The stack is empty. Pop is not allowed\n");
        return 0;
    }
    else
    {
        *stkptr = temp->next;
        free(temp);  // Or call the function to deallocate a Node
        return 1;
    }
}

现在成功时返回 1,堆栈为空时返回 0。或者,如果您希望返回而不是释放堆栈顶部的值,那么:

Node *pop(Node **stkptr)
{
    assert(stkptr != 0);
    Node *temp = *stkptr;

    if (temp == NULL)
    {
        fprintf(stderr, "The stack is empty. Pop is not allowed\n");
        return 0;
    }
    else
    {
        *stkptr = temp->next;
         return temp;
    }
}

或者,由于返回值告诉您是否有要弹出的内容,并且在库函数中打印可能会令人反感,甚至可能:

Node *pop(Node **stkptr)
{
    assert(stkptr != 0);
    Node *temp = *stkptr;

    if (temp != NULL)
        *stkptr = temp->next;
    return temp;
}

警告:没有任何代码被提交给编译器进行验证。

【讨论】:

  • 最后一个调用序列的唯一问题是销毁现有堆栈指针,这将阻止您正确释放内存。应该使用第二个变量来确保push 没有返回NULL,类似于realloc 的安全使用。
  • @ChronoKitsune:是的,虽然我已经注意到内存管理没有错误处理。
猜你喜欢
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 2011-01-27
  • 2014-09-13
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多