1 基本概念
与栈的顺序存储相同,栈的链式存储也是基于线性表的链式存储的基础之上完成对栈的设计。其中栈的链式存储部分参考《数据结构之线性表——链表的链式存储(链式描述)》。栈的链式存储结构示意图如下所示:
2 链式栈的具体实现分析
(1)链式栈的存储节点定义
包含链表的指针域节点和用户数据域指针。
typedef struct _tag_LinkStack
{
LinkListNode node;
void * item;
}TLinkStack;
(2)创建链式栈
创建链式栈相当于创建一个链式线性表
//创建一个栈相当于创建一个线性表
LinkStack * LinkStack_Create()
{
return LinkList_Create();
}
(3)销毁链式栈
销毁链式栈涉及到链表节点的生命周期管理。首先,清空栈中锁有元素,然后再销毁栈。
//涉及到链表节点的生命周期的管理
void LinkStack_Destroy(LinkStack * stack)
{
//首先要删除栈的所有元素
LinkStack_Clear(stack);//释放栈中的节点
return LinkList_Destroy(stack);//释放句柄
}
(4)清空链式栈
清空链式栈:当栈的长度不为0时,一直Pop出栈中的元素。直到栈中不存在任何元素。
void LinkStack_Clear(LinkStack * stack)
{
while (LinkList_Length(stack) > 0)
{
LinkStack_Pop(stack);
}
return;
}
(5)链式栈压栈操作
向栈中压入元素相当于链式表的头插法。
//向栈中添加元素,压栈相当于链表的头插法
int LinkStack_Push(LinkStack * stack,void * item)
{
//栈结点转换成链表节点
int ret = 0;
TLinkStack *tmp = NULL;
tmp = (TLinkStack *)malloc(sizeof(TLinkStack));
tmp->item = item;
ret = LinkList_Insert(stack, (LinkListNode*)tmp, 0);//栈结点
if (ret != 0)
{
printf("func LinkList_Insert() err\n");
free(tmp);
}
return ret;
}
(6)链式栈的出栈操作
栈的出栈操作相当于删除链式线性表的头结点
//出栈相当于链表的的头结点删除
void * LinkStack_Pop(LinkStack * stack)
{
TLinkStack *tmp = NULL;
void * item = NULL;//转接一下指针变量
tmp = (TLinkStack *)LinkList_Delete(stack, 0);
if (tmp == NULL)
{
printf("func LinkList_Delete(stack) error \n");
return NULL;
}
//链表节点转化成栈结点
item = tmp->item;
free(tmp);//释放节点元素
tmp = NULL;
return item;
}
(7)获取链式栈的栈顶元素
获取栈顶元素,相当于获取线性表的0号位置元素
void * LinkStack_Top(LinkStack * stack)
{
TLinkStack *tmp = NULL;
void *item = NULL;
tmp = (TLinkStack *)LinkList_Get(stack, 0);
if (tmp == NULL)
{
printf("func LinkList_Get(stack) error \n");
return NULL;
}
item = tmp->item;
return item;
}
(8)获取栈的大小
栈的大小相当于链式线性表的长度。
int LinkStack_Size(LinkStack * stack)
{
return LinkList_Length(stack);
}
3 链式栈的具体实现以及案例测试
//LinkStack.h
#ifndef _MY_LINKSTACK_H_
#define _MY_LINKSTACK_H_
typedef void LinkStack;
LinkStack * LinkStack_Create();
void LinkStack_Destroy(LinkStack * stack);
void LinkStack_Clear(LinkStack * stack);
int LinkStack_Push(LinkStack * stack,void *item);
void * LinkStack_Pop(LinkStack * stack);
void * LinkStack_Top(LinkStack * stack);
int LinkStack_Size(LinkStack * stack);
#endif//_MY_LINKSTACK_H_
//LinkStack.cpp
#include"LinkStack.h"
#include"LinkList.h"
#include
#include
typedef struct _tag_LinkStack
{
LinkListNode node;
void * item;
}TLinkStack;
//创建一个栈相当于创建一个线性表
LinkStack * LinkStack_Create()
{
return LinkList_Create();
}
//涉及到链表节点的生命周期的管理
void LinkStack_Destroy(LinkStack * stack)
{
//首先要删除栈的所有元素
LinkStack_Clear(stack);//释放栈中的节点
return LinkList_Destroy(stack);//释放句柄
}
void LinkStack_Clear(LinkStack * stack)
{
while (LinkList_Length(stack) > 0)
{
LinkStack_Pop(stack);
}
return;
}
//向栈中添加元素,压栈相当于链表的头插法
int LinkStack_Push(LinkStack * stack,void * item)
{
//栈结点转换成链表节点
int ret = 0;
TLinkStack *tmp = NULL;
tmp = (TLinkStack *)malloc(sizeof(TLinkStack));
tmp->item = item;
ret = LinkList_Insert(stack, (LinkListNode*)tmp, 0);//栈结点
if (ret != 0)
{
printf("func LinkList_Insert() err\n");
free(tmp);
}
return ret;
}
//出栈相当于链表的的头结点删除
void * LinkStack_Pop(LinkStack * stack)
{
TLinkStack *tmp = NULL;
void * item = NULL;//转接一下指针变量
tmp = (TLinkStack *)LinkList_Delete(stack, 0);
if (tmp == NULL)
{
printf("func LinkList_Delete(stack) error \n");
return NULL;
}
//链表节点转化成栈结点
item = tmp->item;
free(tmp);//释放节点元素
tmp = NULL;
return item;
}
//获取栈顶元素,相当于获取线性表的0号位置元素
void * LinkStack_Top(LinkStack * stack)
{
TLinkStack *tmp = NULL;
void *item = NULL;
tmp = (TLinkStack *)LinkList_Get(stack, 0);
if (tmp == NULL)
{
printf("func LinkList_Get(stack) error \n");
return NULL;
}
item = tmp->item;
return item;
}
int LinkStack_Size(LinkStack * stack)
{
return LinkList_Length(stack);
}
//test.cpp
#include
#include
#include"LinkStack.h"
int main()
{
LinkStack * stack = NULL;
int a[5], i = 0;
for (i = 0; i < 5; i++)
{
a[i] = i + 1;
}
stack = LinkStack_Create();
for (i = 0; i < 5; i++)
{
LinkStack_Push(stack, &a[i]);//将栈的结点[a[i]]适配成链表结点
}
//获取栈的属性
printf("len : %d \n", LinkStack_Size(stack));
printf("top : %d \n", *((int *)LinkStack_Top(stack)));
while (LinkStack_Size(stack) > 0)
{
int tmp = *((int *)LinkStack_Pop(stack));
printf("%d ", tmp);
}
printf("\n");
LinkStack_Destroy(stack);
return 0;
}