![数据结构(C语言实现)](https://wfqqreader-1252317822.image.myqcloud.com/cover/699/43806699/b_43806699.jpg)
上QQ阅读APP看书,第一时间看更新
3.1.4 链栈
1.栈的链式存储结构
采用链式存储方式的栈称为链栈或链式栈。由于栈的插入与删除操作仅限在表头的位置进行,因此链表的表头指针就作为栈顶指针。通常,链栈采用带头结点的单链表实现。如图3.5所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/74_02.jpg?sign=1738885764-BNj6sJX7jnqhthJ4Lf2DXvbW2rMotd5t-0-7dfdf64faa8cc9b613bc66c0cd2517aa)
图3.5 链栈示意图
在图3.5中,top为栈顶指针,始终指向栈顶元素前面的头结点。链栈的基本操作与链表的类似,在使用完链栈时,应释放其空间。
链栈结点的类型描述如下:
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/74_03.jpg?sign=1738885764-dZocCZFzMwr9QQl5NKRH0MFkWu4kQoQP-0-5f594fec1af7d7d93ebe4aee9cf55773)
链栈的进栈操作与链表的插入操作类似,出栈操作与链表的删除操作类似。关于链栈的操作说明如下:
(1)链栈通过链表实现,链表的第一个结点位于栈顶,最后一个结点位于栈底。
(2)设栈顶指针为top,初始化时,对于不带头结点的链栈,top=NULL;对于带头结点的链栈,top->next=NULL。
(3)不带头结点的栈空条件为top==NULL,带头结点的栈空条件为top->next==NULL。
2.链栈的基本运算
链栈的基本运算具体实现如下(以下算法的实现保存在文件“LinkStack.h”中)。
(1)链栈的初始化。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/74_04.jpg?sign=1738885764-WRkXfSswcfcuTIvo9Kehmc9gAdSJjBsN-0-d02aaecd2551816b35913abba402274b)
(2)判断链栈是否为空。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/74_05.jpg?sign=1738885764-8wkHK1NHfWNrBt4w8Xi49bEBx7gLyqIp-0-48dea2948408dd00ae9c9592284c985e)
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/75_01.jpg?sign=1738885764-szX42LIuTVQ8ihTZJwglpHHYXeE6yAPC-0-d5791d2cf86cb07e3a83c1e513f0d8b9)
(3)进栈操作。进栈操作就是要将新元素结点插入到链表的第一个结点之前,分为两个步骤:①p->next=top->next;②top->next=p。进栈操作如图3.6所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/75_02.jpg?sign=1738885764-IpApRT38KeXpibWwuGWRa3PORrq792ta-0-06d9ae91ea2d983beb498124d43820e4)
图3.6 进栈操作
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/75_03.jpg?sign=1738885764-HKTMnxubxyTOBvYGMaFiF7hq6hEEshKD-0-1069850132ad6c571a967faa340c2e84)
(4)出栈操作。出栈操作就是将单链表中的第一个结点删除,并将结点的元素赋值给e,并释放结点空间。在元素出栈前,要判断栈是否为空。出栈操作如图3.7所示。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/75_04.jpg?sign=1738885764-H4Zwjpazgw7UQxDP3GqtRC4kHWlWOrAW-0-c97e5583b372341d112183a37a56002e)
图3.7 出栈操作
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/75_05.jpg?sign=1738885764-Fk3AWYdUVcBrJfap9augfGMnhPwXYped-0-b1ba42e906b3b1377ab4519d7faf8bc0)
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/76_01.jpg?sign=1738885764-VZXdXaWnI8LjyFOnoW97k3S3bssasE5m-0-825add6f1a61408698e227bff8fa71d7)
(5)取栈顶元素。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/76_02.jpg?sign=1738885764-dSsYxgbkL3SLQCp8EaYcIALj6BEa1Lnq-0-2c52a76f4df203250cb1d2995b92cc50)
(6)求表长操作。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/76_03.jpg?sign=1738885764-4aHB2OulLeJKi8L4tdWGEvnReMMpRtCP-0-28f276506c2fc6579e0bd867811573e7)
在链表中为了求表中元素个数,必须从栈顶指针出发,依次访问每个结点,并利用计数器计数,直到栈底为止。求表长的时间复杂度为O(n)。
(7)销毁链栈。
![](https://epubservercos.yuewen.com/2EFA35/23083815801896206/epubprivate/OEBPS/Images/76_04.jpg?sign=1738885764-2m4vSTdUFHnqm33OH252Uf3Po9RMsqAq-0-d67f8a5aed84b87be3dcc3ba8bb75df9)