首页 > 其他分享 >链式栈

链式栈

时间:2024-04-25 11:22:40浏览次数:17  
标签:LinkStack 结点 Head next Phead 链式 NULL

以链表作为基础实现栈空间(链式栈)

/********************************************************************************
 *
 *  file name:  LinkedStack.c
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  function :  实现链式栈的入栈(Push)与出栈(Pop)
 *  note     :  None
 *
 *  CopyRight  (c)  2023-2024   [email protected]    All  Right  Reseverd
 *   ****************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// 链栈中的元素的数据类型,用户可以根据需求进行修改
typedef int DataType_t;

// 构建记录链栈LinkedStack的各项参数(栈底地址,栈容量,栈顶元素的小标)的结构体
typedef struct LinkedStack
{
    struct LinkedStack *next;
    DataType_t data;
} LinkStack_t;

/************************************************************************
 *  name     :  LinkStack_Dreate
 *  function :  创建一个空的链栈,并对数据域与指针域进行初始化
 *  argument :  None
 *
 *
 *  retval   :  返回头结点的地址
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  note     :  None
 *   *********************************************************************/
LinkStack_t *LinkStack_Create(void)
{
    // 创建一个头结点并对头结点申请内存
    LinkStack_t *Head = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));
    // 判断申请堆内存是否成功
    if (NULL == Head)
    {
        perror("calloc memroy from Head is failed");
        exit(-1);
    }

    // 进行初始化
    Head->next = NULL;

    return Head;
}


/************************************************************************
 *  name     :  LinkStack_NewNode
 *  function :  创建一个新的结点并对数据域与指针域进行初始化
 *  argument :
 *              @Data :入栈的数据
 *
 *  retval   :  返回新结点的地址
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  note     :  None
 *   *********************************************************************/
LinkStack_t *LinkStack_NewNode(DataType_t Data)
{
    // 1.创建一个新结点并对新结点申请内存
    LinkStack_t *New = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));
    if (NULL == New)
    {
        perror("Calloc memory for NewNode is Failed");
        return NULL;
    }

    // 对新结点的指针域与数据域进行初始化
    New->data = Data;
    New->next = NULL;

    return New;
}


/************************************************************************
 *  name     :  LinkStack_Push
 *  function :  入栈
 *  argument :  
 *              @Head :头结点的地址
 *              @Data :入栈的数据
 *  retval   :  true and false
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  note     :  None
 *   *********************************************************************/
bool LinkStack_Push(LinkStack_t *Head, DataType_t Data)
{
    // 创建一个新的结点
    LinkStack_t *New = LinkStack_NewNode(Data);
    if (NULL == New)
    {
        printf("can not insert new node!\n");
        return false;
    }

    // 如果链栈为空
    if (NULL == Head->next)
    {
        // 头结点的next指针指向新结点
        Head->next = New;
        return true;
    }

    // 链栈为非空
    New->next = Head->next; // 新结点的next指针指向首结点
    Head->next = New;       // 头结点的next指针指向新结点

    return true;
}

/************************************************************************
 *  name     :  LinkStack_Pop
 *  function :  出栈
 *  argument :  
 *              @Head :头结点的地址
 *              
 *  retval   :  true and false
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  note     :  None
 *   *********************************************************************/
bool LinkStack_Pop(LinkStack_t *Head)
{
    LinkStack_t *Phead = Head->next; // 备份首结点
    // 判断链栈是否为空
    if (NULL == Head->next)
    {
        printf("Linked Stack is empty!\n");
        return false;
    }

    // 链栈不为空
    if (NULL == Phead->next) // 链栈中只有一个首结点
    {
        Head->next = NULL; // 头结点的next指针指向NULL
        free(Phead);       // 释放首结点内存
    }
    else
    {
        Head->next = Phead->next; // 头结点指向待删除结点的直接后继
        Phead->next = NULL;       // 待删除结点的next指针指向NULL
        free(Phead);              // 释放删除结点的内存
    }
}

/************************************************************************
 *  name     :  LinkStack_Print
 *  function :  遍历链式栈的每个结点并输出每个结点的数据与的值
 *  argument :  
 *              @Head :头结点的地址
 *              
 *  retval   :  true and false
 *  author   :  [email protected]
 *  date     :  2024/04/25
 *  note     :  None
 *   *********************************************************************/
bool LinkStack_Print(LinkStack_t *Head)
{
    // 对单向循环链表的头结点的地址进行备份
    LinkStack_t *Phead = Head;

    // 判断当前链表是否为空,为空则直接退出
    if (NULL == Head->next)
    {
        printf("current linked stack is empty!\n");
        return false;
    }

    // 从首结点开始遍历
    while (Phead->next)
    {
        // 把头结点的直接后继作为新的头结点
        Phead = Phead->next;

        // 输出头结点的直接后继的数据域
        printf("data = %d\n", Phead->data);

        // 判断是否到达尾结点,尾结点的next指针是指向首结点的地址
        if (Phead->next == NULL)
        {
            break;
        }
    }

    return true;
}

int main(void)
{
    LinkStack_t *Head = LinkStack_Create();
    LinkStack_Push(Head, 1);
    LinkStack_Push(Head, 2);
    LinkStack_Push(Head, 3);
    LinkStack_Print(Head);

    LinkStack_Pop(Head);
    LinkStack_Pop(Head);
    LinkStack_Pop(Head);
    LinkStack_Pop(Head);
    LinkStack_Print(Head);
    LinkStack_Push(Head, 1);
    LinkStack_Print(Head);
}

标签:LinkStack,结点,Head,next,Phead,链式,NULL
From: https://www.cnblogs.com/Yxwwant/p/18157218

相关文章

  • C语言数据结构:链式栈及其出入栈
    /***********************************************************************************************************实现链式栈一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除,链式栈相当于是一个单向不循环的链表。****Copyright(c)2023-2......
  • 链式栈————出栈、入栈
    以链表作为基础实现栈空间(链式栈)如果打算实现链式栈,一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除(头插+头删),链式栈相当于是一个单向不循环的链表。链式栈要注意的点:出栈要考虑栈是否为空入栈要考虑栈中是否有数据以下是我的代码:/******************......
  • 挑战前端基础120题--JavaScript 中如何实现链式调用的函数?
    一.何为链式调用?链式调用是一种简化过程的编码方式,使代码看起来更加简洁~它允许你通过在方法调用之间返回对象本身,从而连续地调用多个方法;比较常见的链式调用:jQuery,Promise等,通过多次书写.或()操作来调用。二.实现的原理?每次执行完成后返回自己/新的自己,这样可以确保后续的......
  • 栈2: 链式存储
    栈2:栈的链式存储栈的结点//链式栈的结点typedefstructLINKNODE{structLINKNODE*next;}LinkNode;链式栈的结构//链式栈typedefstructLINKSTACK{LinkNodehead;intsize;}LinkStack;栈的初始化LinkStack*Init_LinkStack(){LinkStack*s......
  • 队列链式实现
    链式存储实现的队列:链队列typedefstructLinkNode{//链式队列结点ElemTypedata;structLinkNode*next;}LinkNode;typedefstruct{//链式队列LinkNode*front,*rear;//队列的队头和队尾指针}LinkQueue;带头结点:不......
  • C语言链表:链式魔法,数据之美
    导入链表,作为C语言中一种基础且重要的数据结构,以其独特的方式组织和存储数据,成为了解决许多复杂问题的关键。下面,我们将更具体地探讨C语言链表的各个方面。一、链表的基本结构链表由一系列节点组成,每个节点通常包含两部分:数据域和指针域。数据域用于存储实际的数据,而指针域......
  • 链式队列实现
    typedefstructlist//创建队列中的链式结构{ datatypedata;//数据域 structlist*next;//指针域}list;typedefstructqueue//创建队列{ list*front;//队头 list*rear;//队尾}queue;voidinitqueue(queue*q)//初始化队列{ q->front=q->rear=(list*)mal......
  • 数据结构 —— 线性表的链式存储(链表)(C++)
    目录单链表(有头结点)定义初始化判空销毁清空求表长取值查找插入删除创建头部创建尾部创建本文相关知识:以链式存储结构来实现线性表(C++)如有错误请指正~~谢谢~后面更新循环链表和双向链表单链表(有头结点)以带头结点的单链表为例,操作更加简便!定义首先,为了增强程序的可读性,做出以......
  • 链式栈回文字符串的判断(C++版)
    大家好我是大一新生,如果代码有啥错误和改进的地方可以评论哦,谢谢观念看;#include<iostream>#include<iomanip>usingnamespacestd;#defineok1#defineerror0#defineSelemtypechar#defineStatusint#defineMAXSIZE100typedefstructstack{//链式栈的结构  ......
  • 线性表的链式表示--定义与初始化
    链表与数组不同点在于数组是采用随机存取,可根据第一个数据的位置退出其他任何数据的位置,而链表则采用顺序存取,想要取出第i个数据必须从头指针出发顺链表寻找。一.定义    链表的每一个节点应该包括它的数据域以及指针域。因此单链表的存储结构为二.初始化  ......