一、链式栈的管理结构体、节点设计
图解:
示例代码:
// 单向链表的节点设计
typedef struct node
{
// 数据域
int data;
// 指针域
struct node *next_p;
}node_t, *node_p;
// 链式栈的管理结构体设计
typedef struct link_stack
{
node_p top_p; // 链式栈的栈顶指针
int size; // 链式栈的当前的元素个数
}link_stack_t, *link_stack_p;
二、初始化链式栈(空栈)
图解:
示例代码:
/**
* @brief 初始化链式栈
* @note None
* @param None
* @retval 成功:返回指向这个链式栈管理结构体的指针
* 失败:返回NULL
*/
link_stack_p LINK_STACK_Init(void)
{
// 1、申请内存空间
link_stack_p p = malloc(sizeof(link_stack_t));
bzero(p, sizeof(link_stack_t));
// 2、给堆内存空间赋值
if ( p!= NULL)
{
// a、初始化头节点
p->top_p = malloc(sizeof(node_t));
bzero( p->top_p, sizeof(node_t));
if ( p->top_p != NULL)
{
// 数据域不用赋值
// 指针域
p->top_p->next_p = NULL;
}
else
{
free(p);
return NULL;
}
// b、链式栈的当前的元素个数(记录由几个数据节点)
p->size = 0;
}
// 3、成功返回指向这个链式栈管理结构体的指针
return p;
}
三、初始化数据节点,并且入栈
图解:
示例代码:
/**
* @brief 初始化数据节点,并且入栈
* @note 创建数据节点的功能也一并加入
* @param None
* @retval 成功:返回0
* 失败:返回非0
*/
int LINK_STACK_Push(link_stack_p p, int data)
{
// 1、创建数据节点
node_p new_node = malloc(sizeof(node_t));
bzero(new_node, sizeof(node_t));
if ( new_node != NULL)
{
// 数据域赋值
new_node->data = data;
// 指针域
new_node->next_p = NULL;
}
// 2、将这个数据节点进行入栈操作
node_p head_node = p->top_p;
new_node->next_p = head_node->next_p;
head_node->next_p = new_node;
// 3、更新size数据
p->size++;
// 4、成功返回0、
return 0;
}
四、判断链式栈是否为空
示例代码:
/**
* @brief 判断链表是否为空
* @note None
* @param p:链式栈的管理结构体指针
* @retval 如果链表为空: 返回true
* 如果链表为非空:返回false
*/
bool LINK_STACK_IfEmpty(link_stack_p p)
{
return (p->top_p->next_p == NULL);
}
五、遍历整个链式栈
图解:
示例代码:
/**
* @brief 遍历整个链式表
* @note None
* @param p:链式栈的管理结构体指针
* @retval 成功:返回0
* 失败:返回非0
*/
int LINK_STACK_ShowStack(link_stack_p p)
{
// 1、判断链表是否为空,是的话,返回-1
if (LINK_STACK_IfEmpty(p))
return -1;
// 2、遍历整个链表,并逐个打印里面的数据
node_p tmp_p = NULL;
int i = 0;
printf("================链式表中的数据====================\n\n");
for (tmp_p = p->top_p->next_p, i = p->size-1; tmp_p != NULL; tmp_p = tmp_p->next_p, i--)
{
printf("link_stack[%d] = %d\n", i, tmp_p->data);
}
printf("===================================================\n");
// 3、成功返回0
return 0;
}
六、出栈 --- 删除栈顶数据
图解:
示例代码:
/**
* @brief 出栈 --- 删除数据节点
* @note None
* @param p:链式栈的管理结构体指针
* @retval 成功:返回0
* 失败:返回非0
*/
int LINK_STACK_Pop(link_stack_p p)
{
// 1、判断链式栈是否为空
if (LINK_STACK_IfEmpty(p))
return -1;
// 2、将栈顶数据删除
node_p last_node = p->top_p;
node_p del_node = last_node->next_p;
node_p next_node = del_node->next_p;
last_node->next_p = next_node;
free(del_node);
// 3、将链式栈的数据节点个数减1
p->size--;
// 4、成功返回0
return 0;
}
七、获取或修改栈顶数据
图解:
示例代码:
/**
* @brief 获取或修改栈顶数据 --- 查改功能
* @note None
* @param p: 链式栈的管理结构体指针
* data:
* @retval 成功:返回读取的栈顶的数据
* 失败:返回NULL
*/
int* LINK_STACK_GetTopData(link_stack_p p)
{
// 1、判断链式栈是否为空
if (LINK_STACK_IfEmpty(p))
return NULL;
// 2、成功返回栈顶数据的指针
return &(p->top_p->next_p->data);
}
八、销毁整个链式栈
图解:
示例代码:
/**
* @brief 销毁整个链式栈
* @note None
* @param p:链式栈的管理结构体指针
* @retval 成功:返回0
* 失败:返回非0
*/
int LINK_STACK_UnInit(link_stack_p p)
{
// 1、一个个删除并释放数据节点
node_p tmp_p = NULL; // 是用来遍历的
node_p last_node = p->top_p;
node_p del_node = last_node->next_p;
node_p next_node = del_node->next_p;
for (tmp_p= last_node; tmp_p->next_p!=NULL; tmp_p=tmp_p->next_p)
{
// a、删除节点并释放其内存
last_node->next_p = next_node;
free(del_node);
// b、轮回继续
del_node = next_node;
next_node = next_node->next_p;
}
if (tmp_p->next_p==NULL) // 最后还有一个数据节点,也将其删除并释放了
{
last_node->next_p = next_node;
free(del_node);
}
// 2、释放头节点和链式栈的管理结构体
free(last_node);
free(p);
// 3、成功返回0
return 0;
}
以上的内容属于我的课后笔记