链式栈————遍历、出栈、入栈 (基于C语言实现)
以链表作为基础实现栈空间(链式栈)
如果打算实现链式栈,一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除(头插+头删),链式栈相当于是一个单向不循环的链表。
链式栈要注意的点:
- 出栈要考虑栈是否为空
- 入栈要考虑栈中是否有数据

以下是我的函数接口:
定义链式栈中的元素类型
// 指的是链式栈中的元素的数据类型,用户可以根据需要进行修改
typedef int DataType_t;
构造记录链式栈LinkStack各项参数(栈底地址+栈容量+栈顶元素的下标)的结构体
// 构造记录链式栈LinkStack各项参数(栈底地址+栈容量+栈顶元素的下标)的结构体
typedef struct LinkStack
{
struct LinkStack *next; // 结点的指针域,指向下一个结点
DataType_t data; // 结点的数据域
} LinkStack_t;
创建一个空栈链表,空链表应该有一个头结点,对链表进行初始化
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 : 出栈的结点的数据
* author : Dazz
* date : 2024/4/25
* note : None
*
* *******************************************************/
DataType_t LinkStack_Pop(LinkStack_t *Head)
{
// 判断链式栈是否为空
if (NULL == Head->next)
{
printf("栈为空,无法出栈\n");
return false;
}
LinkStack_t *temp = Head->next; //备份首结点;
DataType_t Data = temp->data; //记录需要出栈的数据
// 栈中只有一个结点的情况
if (NULL == Head->next->next)
{
Head->next = NULL; // 将头结点的指针域指向NULL
temp->next = NULL; // 将该结点的指针域指向NULL
free(temp); // 释放该结点
}
else // 栈中不只有一个结点的情况
{
Head->next = temp->next; // 将头节点的指针域指向首结点的直接后继
temp->next = NULL; // 将该结点的指针域指向NULL
free(temp); // 释放该结点
}
return Data;
}
判断栈是否为空
/******************************************************
*
*
* 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;
}
}

浙公网安备 33010602011771号