在这篇博客中我们实现栈的链式存储结构,其实与普通线性表的链式存储结构实现大同小异,但在这里我会解析一下实现过程中碰到的一个坑,即数组传参的问题。
先放源码:
/*
栈的链式结构实现
*/
#include <stdio.h>
#include <Windows.h>
typedef struct Node
{
int data;
struct Node* next;
}Node, *NodePtr;
typedef struct
{
NodePtr top; //头指针
int length; //栈的长短
}linkstack, * linkStack;
//打印栈
void showStack(linkStack S);
//入栈
void append(linkStack S, int value);
//出栈
int pop(linkStack S);
void showStack(linkStack S)
{
NodePtr move = S->top;
int i = 0;
while (move != NULL)
{
printf("%d: %d\n", ++i, move->data); //打印数据
move = move->next; //将move指向下一个节点
}
printf("栈长: %d\n\n", S->length);
}
//void append(Stack S, int value)
//{
// Node* move = S;
//
// S = (Stack)malloc(sizeof(Node)); //新建一个节点
// S->data = value; //赋值
// S->next = move; //串起来
//}
void append(linkStack S, int value)
{
NodePtr move = (NodePtr)malloc(sizeof(Node)); //新建一个节点
move->data = value; //赋值
//将新节点插到首位
move->next = S->top;
S->top = move;
S->length++; //栈长加一
}
int pop(linkStack S)
{
if (S->length == 0)
{
printf("S为空栈!\n");
return;
}
NodePtr move = S->top; //记住栈顶的位置
int value = S->top->data; //记住首位的值
S->top = S->top->next; //移动栈顶
free(move); //释放原栈顶的内存
S->length--; //栈长减一
return value; //返回出栈的值
}
int main(void)
{
//初始化一个长度为10 的栈
linkStack S = (linkStack)malloc(sizeof(linkstack)); //创建头指针,栈顶
S->length = 10;
S->top = (NodePtr)malloc(sizeof(Node));
S->top->data = 1;
Node* move = S->top;
for (int i = 0; i < 9; i++)
{
move->next = (NodePtr)malloc(sizeof(Node)); //创建新节点
move = move->next; //移动move指针
move->data = i + 2; //赋值
}
move->next = NULL; //尾结点的next指针指向空
//打印栈
showStack(S);
//加入元素99并打印
append(S, 99);
showStack(S);
//栈顶元素出栈并打印
int k = pop(S);
printf("出栈元素:%d\n\n", k);
showStack(S);
system("PAUSE");
return 0;
}
上面的源码是我修改之后的,现在我们看下之前有错误的源码:
栈的结构:
typedef struct Node
{
int data;
struct Node* next;
}Node, *linkedStack;
入栈的函数:
void append(Stack S, int value)
{
Node* move = S;
S = (Stack)malloc(sizeof(Node)); //新建一个节点
S->data = value; //赋值
S->next = move; //串起来
}
可以看到在这里我是没有给链表加头结点的,然后在实验这个入栈的函数时,我发现在调用这个函数之后,栈的元素没有发送任何改变。
准确地说,在调用函数时,有新元素入栈,但在调用结束,返回主函数后,栈的元素又变回了原来的样子。
我们分析一下append函数的实现,我将元素99入栈,并把该节点插到栈顶,把头指针指向新节点,看似完美无缺,实际上忽略了一个问题:C语言中函数调用参数时,调用的是形参而不是实参。
这是什么意思呢?就是