栈和队列是两种重要的线性结构。从数据结构角度看,栈和队列也是线性表,其特殊性在于站和队列的基本操作是线性表操作的子集,它们的操作受线性表限制。但从数据类型角度看,它们是和线性表不相同的两类重要的抽象数据类型。
1.栈
栈是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有特殊的含义,称为栈顶,表头端称为栈底。栈的修改是按先进后出的原则进行的,因此栈又称为后进先出的线性表。
- 顺序栈的表示和实现
#define MAXSIZE 100 typedef struct { SElemType *base; //栈底指针 SElemType *top; //栈顶指针 int stacksize; //栈可用的最大容量 }SqStack;
- 初始化
【算法步骤】
- 为栈分配一个最大容量为MAXSIZE的数组空间,使base指针指向其基地址,即栈底。
- 栈顶指针top初始化为base,表示栈为空。
- stacksize置为栈的最大容量MAXSIZE。
【算法描述】
void InitStack(SqStack &s)
{
s.base=new SElemType[MAXSIZE];
if(!s.base) exit(0); //存储分配失败
s.top=s.base; //top初始为base,空栈
s.stacksize=MAXSIZE;
}
- 入栈
【算法描述】
- 判断栈是否满,若满则返回错误。
- 将新元素压入栈顶,栈顶指针加1.
【算法描述】
void Push(SqStack &s, SElemType e)
{
if(s.top-s.base==s.stacksize) exit(0);
*s.top++=e;
}
- 出栈
【算法描述】
- 判断栈是否空,若空则返回错误。
- 栈顶指针减1。
【算法描述】
void Pop(SqStack &s)
{
if(s.top==s.base) exit(0);
s.top--;
}
2.队列
和栈相反,队列是一种先进先出的线性表。它只允许在表的一段进行插入,而在另一端删除元素。队列其本身分为多种队列,如循环队列和顺序队列等。
- 循环队列的表示与实现
-
#define MAXQSIZE 100 typedef struct { QElemType *base; int front; //头指针 int rear; //尾指针 }SqQueue;
- 初始化
【算法步骤】
- 为队列分配一个最大容量为MAXSIZE的数组空间,使base指针指向其首地址。
- 将头指针t和尾指针初始化为0,表示队列为空。
【算法描述】
void InitQueue(SqQueue &q)
{
q.base=new QElemType[MAXQSIZE];
if(!q.base) exit(0);
q.front=q.rear=0;
}
- 求队列长度
int QueueLength(SqQueue q)
{
return (q.rear-q.front+MAXQSIZE)%MAXQSIZE;
}
- 入队
【算法步骤】
- 判断队列是否满,若满则报错。
- 将新元素插入队尾。
- 队尾指针加1。
【算法描述】
void EnQueue(SqQueue &q, QElemType e)
{
if( (q.rear+1)%MAXQSIZE==q.front ) exit 0;
//如果指针在循环意义上加1后等于头指针,表示队满
q.base[q.rear]=e;
q.rear=(q.rear+1)%MAXQSIZE;
}
- 出队
【算法步骤】
- 判断队列是否为空,若是空则报错。
- 队头指针加1。
【算法描述】
void DeQueue(SqQueue &q)
{
if(q.front==q.rear) exit 0;
q.front=(q.front+1)%MAXSQIZE;
}