栈的链式存储结构及实现

本文详细阐述了如何利用单链表实现栈的基本概念、定义及其在现实生活中的应用,包括手枪子弹夹、浏览器后退键和编辑软件撤销功能。接着,深入介绍了栈的链式存储结构和实现细节,如初始化、入栈、出栈和清空栈的操作。通过具体的代码示例,解释了如何在链表中实现这些操作,特别强调了入栈操作的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【美团测试题3】用单链表实现栈,栈顶指针为Top,入栈一个p操作是,步骤为?


1 栈的定义

1.1 生活中栈

  1. 手枪的子弹夹就是先放进去的子弹最后才会打出来。
    这里写图片描述
  2. 浏览器中的“后退”键,只要你点击,就会按照你访问顺序的逆序加载浏览过的网页,就是你最后一次的页面肯定是最先加载出来的。
    这里写图片描述
  3. 很多软件例如word,source insight等编辑工作的软件都有撤销(undo)按钮,用的也是栈。

1.2 栈的定义

1、栈是限定仅在表尾进行插入和删除操作的线性表。

这里写图片描述

  • 栈元素具有线性关系,只是一种特殊的线性表,只最后进表的地方插入删。

2、 栈是后进先出的线性表。
这里写图片描述

  • 插入
    这里写图片描述
  • 删除
    这里写图片描述

2 栈的抽象数据类型

这里写图片描述

3、栈的链式存储结构及实现

3.1 设计链栈

  • 栈的链式存储结构也称为链栈(LinkStack)

  • 链表——{头指针head、data、next}
    链栈——{栈顶指针top、data、next}
    这里写图片描述

  • 链表——{头结点(head+size、数据结点(data+next)}
    链栈——{栈顶结点(top+size、数据结点(data+next)}
    这里写图片描述

写代码喽

#include <stdio.h>
#include <malloc.h>
typedef int SElemType;
typedef struct StackNode
{
    SElemType data;
    StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack
{
    LinkStackPtr top;
    int          size;
}LinkStack;

3.2 最简单的那些个操作啦(和单链表基本一样)

3.2.1 栈的状态

  1. 空栈——top指向空,size为0;只有一个栈顶结点。
  2. 栈满——一般不会,除非内存不够用了。。。

3.2.2 构造栈

  1. 创建栈顶结点StackNode
  2. 初始化结点里的值;top = NULL;size = 0;
/*  构造一个空栈S */
void InitStack(LinkStack *S)
{ 
    S->top = (LinkStackPtr)malloc(sizeof(StackNode));
    if(S->top != NULL) return;
    S->top = NULL;
    S->size = 0;
}

3.2.3 插入一个结点,入栈即push
看图理过程,后面有文字

  • 这里写图片描述
  • 这里写图片描述
  • 这里写图片描述
  • 创建栈数据结点
/*创建一个链表数据结点*/
StackNode* BuyNode(SElemType value)
{
    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
    if(newNode = NULL)return ;
    newNode->data = value;
    newNode->next = NULL;
    return newNode;
}

2 .让链栈头结点指向新插入的结点。因为栈顶指针top永远都指向最后一个插入的结点。

/*插入元素value为新的栈顶元素*/
bool push(LinkStack *S,  SElemType value)
{
    StackNode* newNode = BuyNode(value);
    if(newNode == NULL) return ;
    newNode->next=S->top;   /*把当前的栈顶元素赋值给新结点的直接后继,见图中① */
    S->top=newNode;         /*将新的结点s赋值给栈顶指针,见图中② */
    S->size++;
}

3.2.4 出栈,删除一个栈数据元素,只能是栈顶元素
和单链表差不多,直接上代码
这里写图片描述

/*判空*/
bool StackEmpty(LinkStack *S)
{
    if(S == NULL || S->top == NULL || S->size == 0)
        return true;
}
/*获取栈顶元素*/
StackNode* GetTop(LinkStack *S)
{
    if (StackEmpty(S))  return false;
    else return S->top; 
}
/*删除栈顶元素*/
bool pop(LinkStack *S)
{
    if (StackEmpty(S))  return false;
    StackNode * e = GetTop(S);
    S->top = e->next;
    S->top--;
    return true;
}

3.2.6 清空链栈
1、目的

  • 这里写图片描述

2、做法

  • 这里写图片描述

3、代码

/* 清空栈S*/
void ClearStack( LinkStack *S)
{
    if(S == NULL || S->top == NULL )    return ;
    for(StackNode *p = S->top; p!=NULL; p=p->next)
    {
        free(p);
        if(p!=NULL)   p=NULL;
    }
    S->size = 0;   //注意!
}

代码有一个致命错误,你看出来了吗?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值