数据结构——第二章栈、队列:01栈
1.栈和队列是限定插入和删除只能在表的端点进行的线性表。栈是后进先出的数据结构,队列是先进先出的数据结构(栈相当于一个瓶子,向瓶内放的物品被压到瓶子底部,只有等上面的所有物品都出来了,下面的才能出来,这是先进后出;队列相当于一个隧道,火车向隧道内开不能回头,车头先进去也先出来,这是先进先出)。
2.栈的类型定义:
ADT Stack
{
数据对象:D = {ai | ai ∈ ElemSet,i = 1, 2, ..., n, n >= 0}
数据关系:R1 = {<ai-1, ai ∈ D,i=2, ..., n>}(约定an端为栈顶,a1端为栈底)
基本操作:
①InitStack(&S)——初始化栈
②Destroy(&S)——销毁栈
③StackLength(S)——求栈中元素个数
④StackEmpty(S)——判断栈是否为空
⑤GetTop(S, &elem)——返回栈底元素
⑥ClearStack(&S)——清空栈
⑦Push(&S, elem)——进栈
⑧Pop(&S, &elem)——出栈
⑨StackTravers(S, visit())——对栈进行遍历
} ADT Stack
3.栈的实现:
(1)顺序栈:类似于线性表的顺序映像实现,指向表尾的指针可以作为栈顶指针。
#define STACK_INIT_SIZE 100 //栈的顺序存储表示
typedef struct
{
SElemType* base;
SElemType* top;
int stacksize;
} SqStack; //非空栈时top指针始终指向栈顶元素的下一个位置
①初始化栈的操作:
Status InitStack(SqStack &S, int maxsize) //构造一个最大空间为maxsize的空顺序栈S
{
S.base = new ElemType[maxsize];
if (!S.base)
{
exit(OVERFLOW); //存储分配失败
}
S.top = S.base;
S.stacksize = maxsize;
return OK;
}
②进栈操作:
Status Push(SqStack &S, SElemType elem) //若栈不满,则将元素e插入栈顶
{
if (S.top - S.base >= S.stacksize) //栈满
{
return OVERFLOW;
}
*S.top++ = elem;
return OK;
}
③出栈操作:
Status Pop(SqStack &S, SElemType &elem) //若栈不空,删除S的栈顶元素。用elem返回其值,并返回OK,否则返回ERROR
{
if (S.top == S.base)
{
return ERROR;
}
elem = *--S.top;
return OK;
}
(2)链栈:链栈的实现(因为栈中的主要操作是在栈顶插入、删除,在链表的头部做栈顶时最方便的,而且没有必要像单链表那样为了运算方法附加一个头结点)。
typedef struct node
{
SElemType data;
struct node *next;
} StackNode, *LinkStack;
LinkStack top; //top为栈顶指针