数据结构之链式栈的操作(C语言附详细代码与解释)

    学习链式栈之前,我们都已经学过链式表的操作函数;

    对于链式表来说,每一个节点中需要一个数据域指针域,有头链表的头节点是一个数据域无数据,指针域为空的节点;

    再来看栈:入栈与出栈都是在栈的一端进行操作,我们称这一端为栈的顶部,所以我们也需要类似于头节点的东西(栈针)来代表栈顶;

    由于栈的每一个节点的数据都是有效的,新创建的栈节点需要连接上一次创建的栈节点,所以我们不能像链式表那样创建一个空的头节点,所以我们需要一个头指针,也就是栈针,永远指向栈顶;

    不管是链式表还是链式栈,结构体的成员变量都是要包含一个指针域一个数据域。


目录

一,main.c文件

二,linkstack.h头文件

三,linkstack.c文件

1.入栈

2.出栈 

3.linkstack.c详细代码



 

一,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);
    }
}

如果本文中存在代码逻辑,代码完善,解释不通或不清楚的错误,还请批评指正。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值