栈的链式存储结构(链栈):栈顶放在链表的头部,top为头指针,所以基本不存在栈满的情况且无头结点。
空栈:top=NULL
链栈的结构代码:
// 定义结点
typedef struct StackNode
{
type data;
struct StackNode *next;
}StackNode , *LinkStactPtr;
// 定义头指针
typedef struct LinkStact
{
LinkStactPtr=top;
int count;
}LinkStact;
链栈的进栈操作:
若让新元素 s 进栈,首先把栈顶元素赋给 s 的直接后继指针,然后把 s 的地址赋给top指针。
// 代码实现
Status Push(LinkStack *S , type e)
{
LinkStactPtr s= // 给元素 s 分配空间
(LinkStactPtr)malloc(sizeo(StackNode) );
s->data=e; // 存入数据 e
s->next=S->top; // 让s的指针域指向top
S->top=s; // 让 top 指向s
S->count++; // 链栈的结点的个数+1
return OK;
}
链栈的出栈操作:
若要删除栈顶结点 ai ,首先创建结点p存储结点ai,把top指针后移一位,释放p结点。
代码实现:
Status Pop(LinkStack *S , type e)
{
LinkStactPtr p; // 创建结点p
if(StackEmpty (*S) ) // 判断是否为空栈
return ERROR;
*e=S->top->data; // 存储要删除元素的数据
p=S->top; // 把要删除的结点赋给p
S->top=S->top->next; // top后移一位
free(p); // 删除结点 赋给p是为了这个操作
S->count - - ; // 结点个数-1
return OK;
}
总结:如果栈的使用过程中元素的变化不可预料,有时很小,有时非常大,最好使用链栈。反之,如果清楚它的变化范围,用栈的顺序存储结构比较好。