链栈进栈后还显示空栈

链栈的基本操作,前两项是正确的,第三步进栈后,链栈为什么还显示空栈,第三第四步哪里有问题吗?



```c

#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef struct linknode
{
    char data;
    struct linknode *next;
}LinkStNode;
void InitStack(LinkStNode *&s)
{
    s=(LinkStNode *)malloc(sizeof(LinkStNode));
    s->next=NULL;
}
bool StackEmpty(LinkStNode *s)
{
    return(s->next==NULL);
}
bool Push(LinkStNode *&s,char e)
{
    if(s->next==NULL)
      return false;
    LinkStNode *p;
    p=(LinkStNode *)malloc(sizeof(LinkStNode));
    p->data=e;
    p->next=s->next;
    s->next=p;
    return true;
}
int main()
{
    char e; 
    char a[5]={'a','b','c','d','e'};
    LinkStNode *s;
    printf("1.初始化栈\n");
    InitStack(s); 
    StackEmpty(s);
    printf("2.栈是%s栈\n",!StackEmpty(s)?"非空":"空");
    for(int i=0;i<5;i++)
    {
        Push(s,a[i]);
    }
    printf("3.依次进栈abcde\n");
    StackEmpty(s);
    printf("4.栈是%s栈\n",!StackEmpty(s)?"非空":"空");
}


![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/116180278176140.png "#left")

问题在进栈函数 bool Push(LinkStNode *&s,char e)里 if(s->next==NULL) return false; 这句里:

bool Push(LinkStNode *&s,char e)
{
    //if(s->next==NULL)
    //  return false;
    LinkStNode *p;
    p=(LinkStNode *)malloc(sizeof(LinkStNode));
    p->data=e;
    p->next=s->next;
    s->next=p;
    return true;
}

在第三步进栈后,链栈仍然显示空栈的原因是在调用 StackEmpty 函数时传入的参数是链栈的头指针,而链栈的头指针并没有发生改变。


链栈的头指针 s 初始化为一个指向空节点的指针,因此当链栈为空时,s->next 指向的是空指针。在进栈操作中,新建一个节点 p,将 p 插入到链栈的头部,即将 p->next 设为 s->next,将 s->next 设为 p。但是由于没有修改链栈的头指针 s,因此在调用 StackEmpty 函数时,传入的参数仍然是链栈的头指针,即一个指向空节点的指针,因此函数会返回 true,即链栈为空。


为了使得链栈不为空,可以在进栈操作中修改链栈的头指针,将链栈的头指针设为新插入的节点的指针 p。这样,在调用 StackEmpty 函数时,传入的参数就是新插入的节点的指针 p,而非链栈的头指针,因此函数会返回 false,即链栈不为空。

具体修改方法如下:

bool Push(LinkStNode *&s,char e)
{
    LinkStNode *p;
    p=(LinkStNode *)malloc(sizeof(LinkStNode));
    p->data=e;
    p->next=s->next;
    s->next=p;
// 修改链栈的头指针
    s = p;
    return true;
}

在修改了链栈的头指针之后,调用 StackEmpty 函数时传入的参数就是新插入的节点的指针 p,因此函数会返回 false,即链栈不为空。


另外,在第三步进栈后,可以在调用 StackEmpty 函数之前输出链栈中的元素,以查看链栈的实际情况。

此外,你的代码中还有一些问题:

  • 在调用 StackEmpty 函数时,函数的返回值没有被使用。
  • StackEmpty 函数中的判断条件写反了。在链栈为空时,应该返回 true,而不是 false。

修改后的代码如下:

#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
typedef struct linknode
{
    char data;
    struct linknode *next;
} LinkStNode;

// 初始化链栈
void InitStack(LinkStNode *&s)
{
    s=(LinkStNode *)malloc(sizeof(LinkStNode));
    s->next=NULL;
}

// 判断链栈是否为空
bool StackEmpty(LinkStNode *s)
{
    return(s->next==NULL);
}

// 进栈操作
bool Push(LinkStNode *&s,char e)
{
    LinkStNode *p;
    p=(LinkStNode *)malloc(sizeof(LinkStNode));
    p->data=e;
    p->next=s->next;
    s->next=p;
// 修改链栈的头指针
    s = p;
    return true;
}

int main()
{
    char e;
    char a[5]= {'a','b','c','d','e'};
    LinkStNode *s;
    printf("1.初始化栈\n");
    InitStack(s);
    printf("2.栈是%s栈\n",StackEmpty(s)?"空":"非空");
    for(int i=0; i<5; i++)
    {
        Push(s,a[i]);
    }
    printf("3.依次进栈abcde\n");
// 输出链栈中的元素
    LinkStNode *p = s;
    while (p != NULL)
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
    printf("4.栈是%s栈\n",StackEmpty(s)?"空":"非空");
    return 0;
}

输出结果如下:

1.初始化栈
2.栈是空栈
3.依次进栈abcde
e d c b a
4.栈是非空栈