学习链式栈之前,我们都已经学过链式表的操作函数;
对于链式表来说,每一个节点中需要一个数据域和指针域,有头链表的头节点是一个数据域无数据,指针域为空的节点;
再来看栈:入栈与出栈都是在栈的一端进行操作,我们称这一端为栈的顶部,所以我们也需要类似于头节点的东西(栈针)来代表栈顶;
由于栈的每一个节点的数据都是有效的,新创建的栈节点需要连接上一次创建的栈节点,所以我们不能像链式表那样创建一个空的头节点,所以我们需要一个头指针,也就是栈针,永远指向栈顶;
不管是链式表还是链式栈,结构体的成员变量都是要包含一个指针域一个数据域。
目录
一,main.c文件
与顺序栈的创建空栈的方式不同,链式栈创建空栈,只需要定义一个空指针,将该指针作为栈的头部,始终指向栈顶。该空指针应在main函数中创建,然后在linkstack.c文件的创建空栈函数中进行赋值,所以使用时需要注意区分应该使用值传递还是地址传递。
int main(int argc, char const *argv[])
{
linkstack_t *top;
return 0;
}
linkstack.c文件的创建空栈函数:
top代表着栈的顶部,所以top的指向代表了栈的长度;
//1.创建一个空链式栈
void CreateLinkStack(linkstack_t **top)
{
*top = NULL; //链式栈的空就是栈针指向空
}
二,linkstack.h头文件
在头文件中,需要定义结构体,对函数进行声明;
为了方便对整个程序中的数据类型进行更改,我们可以在头文件中对数据类型进行重定义;
根据链式存储的特点,每个节点中包括数据域和指针域;
对所有函数进行声明;
后文只对前三个功能进行详细解释;
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct linkstack_node
{
datatype data;
struct linkstack_node *next;
}linkstack_t;
//1.创建一个空链式栈
void CreateLinkStack(linkstack_t **p);
//2.入栈
int InLinkStack(linkstack_t **top,datatype data);
//3.出栈
datatype OutLinkStack(linkstack_t **top);
//4.判断为空
int isEpLinkStack(linkstack_t *top);
//5.计算栈的长度
int LengthLinkStack(linkstack_t *top);
//6.获取栈顶数据
datatype GetDataLinkStack(linkstack_t *top);
//7.清空栈
void ClearLinkStack(linkstack_t **top);
#endif
三,linkstack.c文件
1.入栈
入栈时,每新增一个节点,栈针指向都要更改,重新指向刚插入的新节点,我们需要将main函数中的栈针top的地址传入函数,才能对top的值进行更改;
入栈时无非就是先开辟一个新的结构体内存,然后新节点尾部链接前一个节点(也就是栈针指向的上一个节点),最后让栈针top重新指向新节点,入栈结束。
//2.入栈
int InLinkStack(linkstack_t **top,datatype data)
{
linkstack_t *pnew = NULL;
pnew = (linkstack_t *)malloc(sizeof(linkstack_t));
if(NULL == pnew)
{
printf("malloc pnew fail\n");
return -1;
}
pnew->next = *top;
pnew->data = data;
*top = pnew;
return 0;
}
2.出栈
出栈时,从栈顶依次输出节点的内容,每输出一个节点,该节点都要释放掉并指向空,避免占用内存;
首先要判断栈是否为空的,也就是判断一下top是否等于NULL;
然后,需要定义一个结构体类型的临时节点pdel来保存要出栈的节点,栈针top向后移,并保存出栈节点的数据,最后释放该节点并返回该节点的数据,出栈结束。
//3.出栈
datatype OutLinkStack(linkstack_t **top)
{
if(isEpLinkStack(*top))//因为在本函数内,形参是二级指针
{
printf("OutLinkStack fail\n");
}
linkstack_t *pdel;
pdel = *top;
*top = pdel->next;
datatype temp = pdel->data;
free(pdel);
pdel = NULL;
return temp;
}
3.linkstack.c详细代码
#include "linkstack.h"
//1.创建一个空链式栈
void CreateLinkStack(linkstack_t **top)
{
*top = NULL; //链式栈的空就是栈针指向空
}
//2.入栈
int InLinkStack(linkstack_t **top,datatype data)
{
linkstack_t *pnew = NULL;
pnew = (linkstack_t *)malloc(sizeof(linkstack_t));
if(NULL == pnew)
{
printf("malloc pnew fail\n");
return -1;
}
pnew->next = *top;
pnew->data = data;
*top = pnew;
return 0;
}
//3.出栈
datatype OutLinkStack(linkstack_t **top)
{
if(isEpLinkStack(*top))//因为在本函数内,形参是二级指针
{
printf("OutLinkStack fail\n");
}
linkstack_t *pdel;
pdel = *top;
*top = pdel->next;
datatype temp = pdel->data;
free(pdel);
pdel = NULL;
return temp;
}
//4.判断为空
int isEpLinkStack(linkstack_t *top)
{
return top == NULL;
}
//5.计算栈的长度
int LengthLinkStack(linkstack_t *top)
{
int len = 0;
while(top != NULL)
{
len++;
top = top->next;
}
return len;
}
//6.获取栈顶数据
datatype GetDataLinkStack(linkstack_t *top)
{
if(isEpLinkStack(top))
{
printf("isEmpty\n");
return -1;
}
return top->data;
}
//7.清空栈
void ClearLinkStack(linkstack_t **top)
{
if(!isEpLinkStack(*top))
{
OutLinkStack(top);
}
}
如果本文中存在代码逻辑,代码完善,解释不通或不清楚的错误,还请批评指正。