栈是限定仅在表尾进行插入或删除操作的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。栈的最主要特点就是“先进后出”(FILO),或“后进先出”(LIFO)。本文在介绍栈的基本概念的基础上,重点介绍栈的顺序表示及相应的算法。
定义
用链式存储结构表示的栈称为“链栈”,链栈对应于链表。
与顺序表和链表的区别相类似,若是栈中元素的数目变化范围较大或不清楚栈中元素的数目,就应该考虑使用链式存储结构。链栈通常用一个无头结点的单链表表示。由于栈的插入删除操作只能在栈顶进行,而对于单链表来说,在首端插入和删除节点要比尾端相对地容易一些,因此将单链表的首段作为栈顶,即将单链表的头指针作为栈顶指针。
可以采用链表作为栈的存储结构,其结点类型与单链表的结点类型相同。
typedef struct node
{
DataType data;
struct node *link;
} Node;
Node *top;/*定义top指针指向链栈的栈顶结点*/
1.进栈
void Push(Node *top, DataType x)
{
Node *p;
p = (Node *)malloc(sizeof(Node));/*申请一个新的结点,并让指针p指向该结点*/
p->data = x;/*新结点的数据域被赋值为x*/
p->link = top;/*新结点的指针域赋值*/
top = p;/*修改栈顶指针变量*/
}
2.出栈
void Pop(Node *top)
{
Node *q;
DataType x;
if (top != NULL)
{
q = top;/*q指针指向原栈顶位置*/
top = top->link;/*修改栈顶指针的位置*/
free(q);/*回收结点q*/
}
}
3.读栈顶元素
DataType ReadTop(Node *top)
{
DataType x;
if (top != NULL)
{
x = top->data;/*x用来保存原栈顶元素*/
return x;
}
else
{
printf("空栈\n");
exit(-1);
}
}
4.遍历栈
结合出栈和读栈顶元素的算法,再使用循环,便可遍历栈。
void ShowStack(Node *top)
{
Node *q = top;
while (q != NULL)
{
printf("%d", q->data);
q = q->link;
}
}
参考文献:
文益民 张瑞霞 李健 编著,数据结构与算法(第2版),清华大学出版社,P45-47.