链栈的结构
链栈是堆栈的链式存储结构,它的结构和单链表的结构一模一样,每个节点都有一个唯一的后驱节点,其中头节点作为栈顶,尾节点作为栈底。它的入栈和出栈只能在头节点进行,也就是说,它是受限制的单链表。链栈相对于顺序栈最大的优点就是,它可以动态分配内存空间,原则上只要内存允许,不会出现栈满的情况。
也可以这么理解,如果一个单链表只允许在头节点进行增加和删除操作,那么这个单链表就可以叫做链栈,链栈的具体结构图如下:
链栈的定义
我们在程序中声明Node类和LinkedStack类。Node类声明链栈中每个节点的类型。LinkedStack类封装了链栈相关的算法。具体示例代码如下:
public class Node
{
public int Data;//数据元素
public Node Next;//指向下一个节点的指针
public Node(int data)
{
this.Data = data;
}
}
/// <summary>
/// 链栈
/// </summary>
internal class LinkedStack
{
Node top;//栈顶
int _length;//长度
}
在LinkedStack中我们声明了一个栈顶指针top,它代表栈顶元素。_length变量代表链栈中节点的数量。
算法1:入栈
入栈分两种情况
第一种:首次入栈,top==null的情况下,直接给top赋值即可 top=newNode;
第二中:非首次入栈,top!=null,则需要newNode.Next=top;top=newNode; 两个步骤。
public void Push(int data)
{
Node newNode = new Node(data);
if (top == null)
{
top = newNode;
}
else
{
newNode.Next = top;
top = newNode;
}
_length++;
}
算法2:出栈
出栈需要先判断栈是否为空,如果为空,则抛出异常。如果不为空,则直接执行返回当前top指针并且将top指向top的下一个节点top=top.Next;
public Node Pop()
{
if (top == null)
{
return null;
}
Node node = top;
top = top.Next;
_length--;
return node;
}
算法3:获取栈顶元素
先判断栈顶是否为空,如果不为空,直接返回站点元素即可。
public Node Peek()
{
if (top == null)
{
throw new Exception("空栈!");
}
return top;
}
算法4:栈是否为空
top==null的时候栈是空的。
public bool IsEmpty()
{
return top == null;
}
示例代码地址
https://gitee.com/jiamingyuanjin_admin/data_struct/blob/master/DataStruct/06LinkedStack.cs
总结
链栈和顺序栈相比,最大的优点就是可以动态分配存储空间。理论上只要内存不受限制,就不存在栈满的情况,但它的缺点就是需要额外的指针字段,空间使用率较低。