栈_单向链表

news/2024/10/15 12:32:31

利用单向链表设计一个栈,实现“后进先出”的功能

​ 栈内存自顶向下进行递增,其实栈和顺序表以及链式表都一样,都属于线性结构,存储的数据的逻辑关系也是一对一的。

​ 栈的一端是封闭的,数据的插入与删除只能在栈的另一端进行,也就是栈遵循“*后进先出*”的原则。也被成为“LIFO”结构,意思是“last input first output”。

闭合的一端被称为栈底(Stack Bottom),允许数据的插入与删除的一端被称为栈顶(Stack Top),不包含任何元素的栈被称为空栈。

  • l 把数据插入到栈空间的动作被称为入栈或者压栈,英文Push)
  • l 从栈空间中删除数据的动作被称为出栈或者弹栈,英文Pop)

程序结构思路:

​ 根据链表在头部增删比较简单的特性。将单向链表的首结点当作栈顶,尾结点当作粘底,入栈相当于头插操作,出栈相当于头删操作。

程序实现:

/********************************************************************************************
*   file name: StackLList.c
*   author   : liaojx2016@126.com
*   date     : 2024/04/25
*   function : Design stack interface to achieve “last input first output”
*   note     : None
*
*   CopyRight (c)  2023-2024   liaojx2016@126.com   All Right Reseverd 
*
*********************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
//指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int  DataType_t;//构造链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct StackLinkedList
{DataType_t  		 data; //结点的数据域struct StackLinkedList	*next; //结点的指针域}QueueLList_t;/**********************************************************************************************
*   func name       : QueueLList_Create
*   function        : Create a empty stack link list to store hexadecimal digit
*   func parameter  : None
*   return resuolt  : Address of head node
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
QueueLList_t * QueueLList_Create(void)
{//1.创建一个头结点并对头结点申请内存QueueLList_t *Head = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));if (NULL == Head){perror("Calloc memory for Head is Failed");exit(-1);}//2.对头结点进行初始化,头结点是不存储有效内容的!!!Head->next = NULL;//3.把头结点的地址返回即可return Head;
}
/**********************************************************************************************
*   func name       : StackLList_NewNode
*   function        : Create a new node and do initialization
*   func parameter  : 
*                       @data :address of head node 
*   return resuolt  : Address of a new node
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
QueueLList_t * QueueLList_NewNode(DataType_t data)
{//1.创建一个新结点并对新结点申请内存QueueLList_t *New = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));if (NULL == New){perror("Calloc memory for NewNode is Failed");return NULL;}//2.对新结点的数据域和指针域进行初始化New->data = data;New->next = NULL;return New;
}
/**********************************************************************************************
*   func name       : StackLList_Push
*   function        : Do stack push action
*   func parameter  : 
*                       @Head :address of head node @data :Disposed remainder
*   return resuolt  : Stack push success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//头插
bool StackLList_Push(QueueLList_t *Head,DataType_t data){//1.创建新的结点,并对新结点进行初始化QueueLList_t *New = QueueLList_NewNode(data);if (NULL == New){printf("can not insert new node\n");return false;}//2.判断链表是否为空,如果为空,则直接插入即可if (NULL == Head->next){Head->next = New;return true;}//3.如果链表为非空,则把新结点插入到链表的头部New->next  = Head->next;    //新结点的next指针指向原首结点Head->next = New;           //头结点的next指针指向新结点return true;
}
/**********************************************************************************************
*   func name       : StackLList_Pop
*   function        : Stack pop for one node
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Stack pop success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//头删
bool StackLList_Pop(QueueLList_t *Head)
{//当链表为空,删除失败,返回falseif (NULL == Head->next){printf("Stack linklist is empty,headdelete failed\n");return false;}QueueLList_t *Delnode=Head->next;   //备份首结点//printf("next=%#x\n",Head->next->next);//输出出栈的数据printf("the push element data is %d\n",Head->next->data);//删除出栈结点Head->next=Head->next->next;    //头结点的next指针指向首结点的直接后继Delnode->next=NULL;             //原首结点指向NULL,防止内存泄漏free(Delnode);                  //释放内存return true;
}
/**********************************************************************************************
*   func name       : QueueLList_Print
*   function        : Stack data print
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Print success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//遍历
bool QueueLList_Print(QueueLList_t *Head)
{if (Head->next==NULL)   {printf("stack link list is empty\n");return false;}//对链表的头文件的地址进行备份QueueLList_t *Phead = Head;printf("the Stack linkedlist data is \n");//遍历结点,输出数据do{//把头的直接后继作为新的头结点Phead = Phead->next;//输出头结点的直接后继的数据域printf("%d ",Phead->data);}while(Phead->next);printf("\n");return true;
}
//
int main(int argc, char const *argv[])
{QueueLList_t *head=QueueLList_Create();//StackLList_Push 入栈操作,StackLList_Pop 出栈操作,QueueLList_Print 栈遍历输出StackLList_Push(head,0);QueueLList_Print(head);StackLList_Pop(head);QueueLList_Print(head);StackLList_Push(head,1);StackLList_Push(head,6);StackLList_Push(head,4);QueueLList_Print(head);StackLList_Pop(head);QueueLList_Print(head);return 0;
}

测试输出结果:
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/26504.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【排课小工具】面向对象分析探索领域模型

用户向系统中输入课表模板、课程信息以及教师责任信息,系统以某种格式输出每个班级的课表。该用例中的主要参与者包括用户以及系统,除了上述两个主要参与者外,我们从该用例中抽取出可能有价值的名词:课表模板、课程、教师职责、班级以及课表。现在我们只知道下面图示的关系…

【Qt 专栏】Qt Creator 的 git 配置 上传到gitee

1.进入到Qt项目文件夹内,打开 “Git Bash Here” 2.初始化,在“Git Bash Here”中输入 git init 3.加入所有文件,在“Git Bash Here”中输入 git add . (需要注意,git add 后面还有一个点) 4.添加备注,git commit -m "备份" 5.推送本地仓库到gitee(需要事…

报错“Please indicate a valid Swagger or OpenAPI version field”

报错“Please indicate a valid Swagger or OpenAPI version field” 报错信息Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0). 原因…

C++重写

数组 DiscoveredTileIndexed 和 DiscoveredTileSortingCosts 这两个数组是用来存储遍历的方格的,DiscoveredTileSortingCosts存储的是每个方格的消耗,DiscoveredTileIndexed存储的是每个方格的位置即(x,y)。 DiscoveredTileSortingCosts中的消耗和DiscoveredTileIndexed位置是…

【网络知识系列】-- 换个角度理解计算机网络

换个角度理解计算机网络,搭建计网知识框架 所谓换个角度,就是从三层物理设备(物理层、数据链路层、网络层)开始,串联起整个网络的工作原理 可能有些小伙伴看见物理设备天生就犯困,反手就准备关闭文章,且慢!本文只是简单的介绍这几个设备的功能,并不会涉及复杂的底层硬…

C#学习笔记-字段、属性、索引器

字段字段表示与对象或者类型(类或结构体)关联的变量(成员变量),为对象或类型存储数据。与对象关联的字段称为“实例字段”,隶属于某个对象。与类型关联的字段称为“静态字段”,表示某一个类型当前的状态。静态字段使用 static 关键字修饰。字段在没有显示初始化的情况下…

力扣-203. 移除链表元素

1.题目 题目地址(203. 移除链表元素 - 力扣(LeetCode)) https://leetcode.cn/problems/remove-linked-list-elements/ 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。示例 1:输入:head = [1,2…

网络接收全流程

网卡简介 网卡是一块通信硬件。属于数据链路层。用户可以通过电缆或无线相互连接。每一个网卡都有一个独一无二的MAC地址(48位),它被写在卡上的一块ROM中。IEEE负责为网卡销售商分配唯一的MAC地址。 可以在终端运行sudo lshw -C network来查看网卡型号 可以在/lib/modules/$(u…