首页 > 其他分享 >链式栈————出栈、入栈

链式栈————出栈、入栈

时间:2024-04-25 10:35:06浏览次数:24  
标签:LinkStack Head 出栈 入栈 结点 next 链式 NULL

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

如果打算实现链式栈,一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除(头插+头删),链式栈相当于是一个单向不循环的链表。
image

链式栈要注意的点:

  • 出栈要考虑栈是否为空
  • 入栈要考虑栈中是否有数据

以下是我的代码:

/*******************************************************************
 *
 *	file name:	Linkstack.c
 *	author	 :  Dazz
 *	date	 :  2024/04/25
 *	function : 该程序实现链式栈元素的增删改查,目的是提高设计程序的逻辑思维,
 *             另外为了提高可移植性,所以顺序栈中元素的数据类型为DataType_t,
 *             用户可以根据实际情况修改链式栈中元素的类型。
 *
 * 	note	 :  None
 *
 *	CopyRight (c)  2024-202x   [email protected]   All Right Reseverd
 *
 * *****************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

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

// 构造记录链式栈LinkStack各项参数(栈底地址+栈容量+栈顶元素的下标)的结构体
typedef struct LinkStack
{
	struct LinkStack *next; // 结点的指针域,指向下一个结点
	DataType_t data;		// 结点的数据域
} LinkStack_t;

/******************************************************
 *
 *  name      : LinkStack_Create
 *	function  : 创建一个空栈链表,空链表应该有一个头结点,对链表进行初始化
 *  argument  :None
 *  retval    : 头结点的地址
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
LinkStack_t *LinkStack_Create(void)
{
	// 利用calloc为链栈的管理结构体申请一块堆内存
	LinkStack_t *Head = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));

	if (NULL == Head)
	{
		perror("calloc memory for Head is failed");
		exit(-1); // 程序异常终止
	}

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

	return Head;
}

/******************************************************
 *
 *  name      : LinkStack_NewNode
 *	function  : 创建一个新的结点,并对该结点进行初始化(数据域 + 指针域)
 *  argument
 * 				@data :需要传入结点中的数据
 *
 *  retval    : 新结点的地址
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
LinkStack_t *LinkStack_NewNode(DataType_t data)
{
	LinkStack_t *New = (LinkStack_t *)calloc(1, sizeof(LinkStack_t));
	if (NULL == New)
	{
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}

	// 对新结点进行初始化
	New->next = NULL;
	New->data = data;

	return New;
}

/******************************************************
 *
 *  name      : LinkStack_Print
 *	function  : 对链式栈进行遍历并打印每个结点的数据域
 *  argument
 * 				@Head :链式栈的头结点
 *
 *  retval    : None
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
void LinkStack_Print(LinkStack_t *Head)
{
	// 判断链式栈是否为空
	if (NULL == Head->next)
	{
		printf("栈为空\n");
		return;
	}

	// 备份头结点
	LinkStack_t *phead = Head;

	// 对链式栈做遍历
	while (phead->next)
	{
		phead = phead->next;
		printf("%d\n", phead->data);
	}
	return;
}

/******************************************************
 *
 *
 *  name      : LinkStack_Push
 *	function  : 创建新的结点,并对新结点压栈
 *  argument
 * 				@Head :链式栈的头结点
 * 				@Data :入栈结点的数据
 *
 *  retval    : 成功为1,否则为0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool LinkStack_Push(LinkStack_t *Head, DataType_t Data)
{
	// 创建新的结点
	LinkStack_t *New = LinkStack_NewNode(Data);
	if (NULL == New)
	{
		return false;
	}

	if (NULL == Head->next)
	{
		Head->next = New;
	}
	else
	{
		LinkStack_t *temp = Head->next; // 备份首结点
		Head->next = New;				// 将头节点的指针域指向新结点
		New->next = temp;				// 将新结点的指针域指向首结点
	}

	return true;
}

/******************************************************
 *
 *
 *  name      : LinkStack_Pop
 *	function  : 对链式栈进行出栈
 *  argument
 * 				@Head :链式栈的头结点
 *
 *  retval    : 成功为1,否则为0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool LinkStack_Pop(LinkStack_t *Head)
{
	// 判断链式栈是否为空
	if (NULL == Head->next)
	{
		printf("栈为空,无法出栈\n");
		return false;
	}

	// 栈中只有一个结点的情况
	if (NULL == Head->next->next)
	{
		LinkStack_t *temp = Head->next; // 备份该结点
		Head->next = NULL;				// 将头结点的指针域指向NULL
		temp->next = NULL;				// 将该结点的指针域指向NULL
		free(temp);						// 释放该结点
	}
	else // 栈中不只有一个结点的情况
	{
		LinkStack_t *temp = Head->next; // 备份首结点
		Head->next = temp->next;		// 将头节点的指针域指向首结点的直接后继
		temp->next = NULL;				// 将该结点的指针域指向NULL
		free(temp);						// 释放该结点
	}
}

/******************************************************
 *
 *
 *  name      : LinkStack_IsEmpty
 *	function  : 判断栈是否为空
 *  argument
 * 				@Head :链式栈的头结点
 *
 *  retval    : 为空返回1,非空返回0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool LinkStack_IsEmpty(LinkStack_t *Head)
{
	if (NULL == Head->next)
	{
		printf("链表为空\n");
		return true;
	}
	else
	{
		printf("链表不为空\n");
		return false;
	}
}

int main(int argc, char const *argv[])
{
	LinkStack_t *Head = LinkStack_Create();
	LinkStack_Print(Head);

	LinkStack_Push(Head, 999);
	LinkStack_Push(Head, 888);
	LinkStack_Push(Head, 777);
	LinkStack_Print(Head);

	LinkStack_Pop(Head);
	LinkStack_Pop(Head);
	// LinkStack_Pop(Head);
	//  LinkStack_Pop(Head);
	LinkStack_Print(Head);

	LinkStack_IsEmpty(Head);

	return 0;
}

标签:LinkStack,Head,出栈,入栈,结点,next,链式,NULL
From: https://www.cnblogs.com/Dazz24/p/18157023

相关文章

  • 挑战前端基础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++)如有错误请指正~~谢谢~后面更新循环链表和双向链表单链表(有头结点)以带头结点的单链表为例,操作更加简便!定义首先,为了增强程序的可读性,做出以......
  • 输出所有可能的栈的合法出栈序列
    voidlegalstack(tack*st,intin[],intout[],intlen,inti,intj){ intx; staticintnum=1; if(empty(st)&&j>=len) { cout<<"第"<<num++<<"种:"; for(inti=0;i<len;i++) { ......
  • 链式栈回文字符串的判断(C++版)
    大家好我是大一新生,如果代码有啥错误和改进的地方可以评论哦,谢谢观念看;#include<iostream>#include<iomanip>usingnamespacestd;#defineok1#defineerror0#defineSelemtypechar#defineStatusint#defineMAXSIZE100typedefstructstack{//链式栈的结构  ......
  • 线性表的链式表示--定义与初始化
    链表与数组不同点在于数组是采用随机存取,可根据第一个数据的位置退出其他任何数据的位置,而链表则采用顺序存取,想要取出第i个数据必须从头指针出发顺链表寻找。一.定义    链表的每一个节点应该包括它的数据域以及指针域。因此单链表的存储结构为二.初始化  ......
  • 【图论 | 数据结构】用链式前向星存图(保姆级教程,详细图解+完整代码)
    一、概述链式前向星是一种用于存储图的数据结构,特别适合于存储稀疏图,它可以有效地存储图的边和节点信息,以及边的权重。它的主要思想是将每个节点的所有出边存储在一起,通过数组的方式连接(类似静态数组实现链表)。这种方法的优点是存储空间小,查询速度快,尤其适合于处理大规模......