栈和队列是两种重要的线性结构,从数据结构的角度来看,栈和队列也是线性表,其特殊性在于栈和队列的基本操作是线性表操作的子集,是一种操作受限的线性表,就像结构体其实是一种特殊的类一样。
栈
从概念来看,栈是限定仅在表尾进行插入或者删除操作的线性表。因此对栈来说,表尾端有其特殊的含义,我们称之为栈顶(top),相应的,表头称之为栈底(bottom)。不含元素的空表称为空栈。
根据定义来理解,我们知道栈的修改是按照后进先出的原则来进行的,因此栈又称为后进先出的线性表(简称LIFO)。栈的基本操作除了在栈顶进行插入删除操作以外,还有栈的初始化,判空,及取栈顶元素等。
下面给出栈的抽象数据类型的定义;
ADT Stack
{
int Push(stack *S,StackData x);//进栈
int Pop(stack *S,StackData &x);//出栈
int GetTop(StackData &x);//取栈顶
void InitStack(stack *S);//置空栈
int StackEmpty(stack *S);//判栈空否
int StackFull(stack *S);//判栈满否
}
栈的表示和实现
栈的初始化操作为;按设定的初始值分配量进行第一次分配存储,base可称为栈底指针,在顺序栈中它始终指向栈底的位子,相应的有top指针,其初始值指向栈底,即top=base可作为栈空的标记,没当插入新的栈顶元素时候,指针top增一。删除栈顶元素时,指针top减一,因此非空栈的栈顶元素始终指向最后一个元素。
#define StackSize 100
typedef char StackData;
typedef struct { //顺序栈定义
StackDatadata[StackSize]; //栈数组
int top; //栈顶指针
} SeqStack;
int StackEmpty(SeqStack*S) {
//判断栈是否空?空则返回1,否则返回0
return S->top == -1;
}
int StackFull (SeqStack *S) {
//判断栈是否满?满则返回1,否则返回0
return S->top ==StackSize-1;
}
void InitStack(SeqStack *S){ //置空栈
S->top = -1;
}
intPush (SeqStack *S, StackData x) {
//若栈满返回0, 否则新元素 x进栈并返回1
if (StackFull(S) ) return0;
S->data[++S->top] = x; //加入新元素
return1;
}
int Gettop (SeqStack *S, StackData &x) {
//若栈空返回0, 否则栈顶元素读到x并返回1
if ( StackEmpty(S) ) return 0;
x =S->data[S->top];
return 1;
}
int pop (SeqStack *S, StackData &x) {
//若栈空返回0, 否则栈顶元素退出到x并返回1
if ( StackEmpty(S) ) return 0;
x =S->data[S->top--];
return 1;
}
链式栈的操作与实现;
定义;
typedef int StackData;
typedef struct node {
StackData data; //结点数据
struct node * link; //结点链指针
} StackNode;
typedef struct {
StackNode *top; //栈顶指针
} LinkStack
实现;
void InitStack ( LinkStack*S ) {
S->top = NULL;
}
int Push ( LinkStack *S,StackData x ) {
StackNode *p = ( StackNode * ) malloc
( sizeof( StackNode ) );
p->data = x; p->link = S->top;
S->top = p; return 1;
}