【问题标题】:C Stack push functionC堆栈推送功能
【发布时间】:2016-06-22 12:04:05
【问题描述】:

我尝试在 C 中实现一个堆栈,但我得到一个非常奇怪的错误。由于某种原因,我的推送功能不起作用..

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

void push(Node *stack,int val)
{
    Node *p = (Node *)calloc(1,sizeof(Node));
    p->v = val;
    Node *aux = stack;
    if(aux == NULL)
    {
        stack = p;
        return;
    }
    while(aux->next != NULL)
        aux = aux->next;
    aux->next = p;
}

我用 NULL 初始化了我的堆栈

Node *stack = NULL;

我把这个函数称为这样的

push(stack,value)

L.E. 我试图创建一个带有参数双指针的弹出函数,但结果与推送相同。

void pop(Node **l)
{
    if((*l) == NULL)
        return;
    else
    {

        Node *aux,*prev;
        prev = *l;
        aux = prev->next;
        if(aux == NULL)
        {
            free(prev->v);
            free(prev);
            return;
        }
        while(aux != NULL)
        {
            prev = aux;
            aux = aux->next;
        }
        prev->next = NULL;
        free(aux->v);
        free(aux);
    }
}

【问题讨论】:

  • 你得到什么错误?是编译错误还是运行时错误?请edit您的问题并附上错误信息。
  • 你的栈是一个局部变量,在push被调用的范围内不会改变
  • @Costi Ivan 我已经在回答中展示了 push 和 pop 应该如何查找堆栈。

标签: c pointers stack


【解决方案1】:

首先堆栈是满足策略 LIFO(Last Input First Output)的数据组织。也就是在栈顶添加新数据,从栈顶弹出。

您不应添加循环来查找添加新数据的堆栈尾部。

而且你需要通过引用传递栈顶。考虑到函数参数是它的局部变量。因此在你的函数中

void push(Node *stack,int val);

您正在更改将在退出函数后销毁的函数的局部变量stack。原论点不会改变。

内存分配也可能失败你应该以某种方式报告错误。

这是一个演示程序,展示了如何实现函数 pushpop

#include <stdio.h>
#include <stdlib.h>

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

int push( Node **stack, int val )
{
    Node *p = malloc( sizeof( Node ) );
    int success = p != NULL;

    if ( success )
    {
        p->v = val;
        p->next = *stack;
        *stack = p;
    }

    return success;
}

int pop( Node **stack, int *val )
{
    int success = *stack != NULL;

    if ( success )
    {
        Node *p = *stack;
        *stack = ( *stack )->next;
        *val = p->v;
        free( p );
    }       

    return success;
}

int main(void) 
{
    const int N = 10;
    Node *stack = NULL;

    int i = 0;
    int val;

    while ( i < N && push( &stack, i ) ) i++;

    while ( i != 0 && pop( &stack, &val ) ) printf( "%d ", val );

    printf( "\n" );

    return 0;
}

它的输出是

9 8 7 6 5 4 3 2 1 0 

【讨论】:

    【解决方案2】:

    您的推送函数需要一个指向堆栈节点的指针。

    void push(Node **stack, int val) {
      ...
      *stack = p;
      ....
    }
    
    push(&stack, value);
    

    【讨论】:

    • 你能检查一下我的弹出功能吗?
    • @CostiIvan 测试问题:如果你 push() 一个元素然后 pop() 它会发生什么。 (它应该是空的,但是当我查看你的函数时,我相信它不会)你应该写一个函数 printStack(stack)
    • 我做了..pop() 对我的堆栈没有任何作用...我不知道为什么
    • @CostiIvan 与 push() 中的答案相同:如果 aux 为空,您不会更改 *l(多么丑陋的名称),*l 必须设置为空
    【解决方案3】:

    您需要通过引用传递堆栈:

    void push(Node **stack,int val)
    {
        Node *p = (Node *)calloc(1,sizeof(Node));
        p->v = val;
        Node *aux = *stack;
        if(aux == NULL)
        {
            *stack = p;
            return;
        }
        while(aux->next != NULL)
            aux = aux->next;
        aux->next = p;
    }
    

    Andcall as push(&stack,value)

    【讨论】:

      【解决方案4】:

      记得将下一个字段初始化为NULL(p->next)

      由于堆栈是传递给 push 函数的指针,因此函数中指针值的变化不会反映在函数之外。

      即:如果在push函数中,我们设置stack = something,函数外的堆栈指针不会被设置为那个。

      解决方法是将堆栈作为指向指针的指针传入,然后您可以修改指针值)

      void push(Node **stack,int val)
      {
        Node *p = (Node *)calloc(1,sizeof(Node));
        p->v = val;
        p->next = NULL;
        Node *aux = *stack;
        if(aux == NULL)
        {
            *stack = p;
            return;
        }
        while(aux->next != NULL)
          aux = aux->next;
        aux->next = p;
      }
      

      通过以下方式调用它:

      push(&stack, 10);
      

      或者对于初学者来说可能更容易理解,从 push 函数中返回堆栈值。

      Node * push(Node *stack,int val)
      {
        Node *p = (Node *)calloc(1,sizeof(Node));
        p->v = val;
        p->next = NULL;
        Node *aux = stack;
        if(aux == NULL)
        {
          stack = p;
          return stack;
        }
        while(aux->next != NULL)
          aux = aux->next;
        aux->next = p;
      
        return stack;
      }
      

      调用方式:

      stack = push(stack, 10);
      

      【讨论】:

      • calloc 初始化为零。无需将p-&gt;next 显式初始化为NULL。
      猜你喜欢
      • 2014-12-19
      • 2015-11-25
      • 2015-08-11
      • 1970-01-01
      • 2021-09-12
      • 2020-12-19
      • 1970-01-01
      • 2016-12-14
      • 2019-04-26
      相关资源
      最近更新 更多