栈的链式结构,简称为链栈,其本质就是一种链表加栈的抽象数据结构。在创建一个链栈的时候我们首先要定义一个链表。
typedef struct Node
{
int date;//数据域
struct Node* next;//指针域
}List;
此时链表的创建,插入就不详述,直接代码略过,值得一提的是,因为栈是一种先进后出(First In Last out)的一种数据结构,所以链表的插入(即为栈的插入)我们采用头插法。
//创建表头
List* creatList()
{
List* L = (List*)malloc(sizeof(List));
L->next = NULL;
return L;
}
//创建节点
List* creatNode(int date)
{
List* newNode = (List*)malloc(sizeof(List));
newNode->date = date;
newNode->next = NULL;
return newNode;
}
//插入节点
void insertNodeByHead(List* L, int date)
{
List* newNode = creatNode(date);
newNode->next = L->next;
L->next = newNode;
}
接下来,我们再来定义一个链栈
typedef struct linkStack
{
List* top;//充当链表的表头
int stackSize;//表示链栈的大小
}LinkStack;
然后链栈的创建即为初始化
LinkStack* creatStack()
{
LinkStack* ListStack = (LinkStack*)malloc(sizeof(LinkStack));
ListStack->stackSize = 0;//链栈初始大小为0
ListStack->top = creatList();//栈顶指针即为链表表头
return ListStack;
}
对栈的插入,即为对该栈顶指针(链表表头)的插入
void pushLinkStack(LinkStack* ListStack, int date)
{
insertNodeByHean(ListStack->top, date);
ListStack->stackSize++;
}
对于栈的删除,因为栈只能从顶端开始进行删除,所以出栈就只需要把栈顶指针往下移一位即可
void popLinkStack(LinkStack* ListStack)
{
if (ListStack->stackSize == 0)
{
printf("空栈\n");
return;
}
else
{
List* L = ListStack->top;//存储删除的栈顶结点
ListStack->top = ListStack->top->next;//栈顶指针往下移一位
ListStack->stackSize--;
free(L);//删除该栈顶结点
return;
}
}
对于链栈而已,基本不存在栈满的情况,除非是内存已经没有可以使用的空间,而对于空栈来说,就是top=NULL的情况。
所以顺序栈与链栈的插入与删除,时间复杂度是一样的均为O(1),但在空间上,如同线性表一样,顺序栈的大小必须先规定好,如果栈的使用过程中,元素不可控,这时候就需要用链栈了