上文详细的讲解了顺序表与链表的实现,相信大家在顺序表与链表的指基础上,很容易就能学会站和队列,废话不多说,我们马上开始!
🌺栈
🍁栈的定义
假设栈 【s = (a1,a2,……,an) 】,a1为栈底元素,an为栈顶元素。由于栈只能在栈顶进行插入和删除操作,所以进栈次序依次为【a1,a2,……,an】,出栈次序为【an,……,a2,a1】
栈类似于线性表,它也有两种对应的存储方式分别为顺序栈和链栈。
🍁顺序栈
(1)顺序栈的定义
栈的顺序存储类型可描述为
#define MaxSize 100 //定义栈中元素的最大个数
typedef struct
{
SElemtype *base; //栈底指针
SElemtype *top; //栈顶指针
int stacksize //栈可用的最大容量
}SqStack;
(2)顺序栈的初始化
🔺实现原理
💬 代码演示
Status InitStack(SqStack &S)
{//构造一个空栈S
S. base=new SElemType[MaxSize]; //为顺序栈动态分配一个最大容量为MAxsini
if(!S. base) exit(OVERFLOW); //存储分配失败
S. top=S. base; //top初始为base,空栈
S. stacksize=MaxSize; //stacksize置为栈的最大容量MaxSize
return OK;
}
(3)顺序栈的入栈
🔺实现原理
💬 代码演示
Status Push(SqStack &S,SElemType e)
{//插入元素e为新的栈顶元素
if(S.top-S.base==S:stacksize) return ERROR;//栈满
*S. top++=e; //元素e压入栈顶,栈顶指针加1
return OK;
}
(4)顺序栈的出栈
🔺实现原理
💬 代码演示
Status Pop(SqStack &S,SElemType &e)
(//删除S的栈顶元素,用e返回其值
if(S.top==S.base) return ERROR;//栈顶
指针减1,将栈顶元素赋给e //栈顶指针减1,将栈顶元素赋给e
e=*--S.top;
return OK;
)
(5)取顺序栈的栈顶元素
🔺实现原理
💬 代码演示
SElemType GetTop (SqStack S)
{//返回s的栈顶元素,不修改栈顶指针
if(S.top!=S.base) //栈非空
return*(S.top-1); //返回栈顶元素的值,栈顶指针不变
)
🍁链栈
采用链式存储的栈称为链栈。链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现。
栈的顺序存储类型可描述为
typedef struct Linknode
{
ElemType data; //数据域
struct Linknode *next; //指针域
} *LiStack;
🌺队列
🍁队列的定义
队列有两种存储表示,分别为顺序表示与链式表示
🍁队列的顺序表达与实现
(1)队列顺序存储结构
队列的顺序存储结构表示如下:
#define MAXSIZE 100 //队列容量
typedef struct
{
ElemType *base; //存储空间
int front,rear; //队首,队尾
}SqQueue ;
(2)假溢出
如何解决循环链表的这一缺点呢?
🍁循环队列
(1)循环队列的初始化
🔺实现原理
💬 代码演示
Status InitQueue ( SqQueue &Q )
{
Q.base=new ElemType[MAXSIZE];
if(!Q.base) return OVERFLOW;
Q.front=Q.rear=0;
return OK;
}
🌹循环队列的入队
🔺实现原理
💬 代码演示
Status EnQueue(SqQueue &Q,ElemType e)
{
if((Q.rear+1)%MAXSIZE==Q.front) //判满
return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return OK;
}
🌹循环队列的出队
🔺实现原理
💬 代码演示
Status DeQueue(SqQueue &Q, ElemType &e)
{
if( Q.rear==Q.front )
return ERROR; //判空
e = Q.base[Q.front];
Q.front = (Q.front+1)%MAXSIZE;
return OK;
}
🍁链队列
队列的链式存储如图:
队列的链式存储类型可描述为:
typedef struct Qnode
{
ElemType data;
struct QNode * next;
}Qnode,*QueuePtr; //结点
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue; //链队
(1)链栈的初始化
🔺实现原理
💬 代码演示
Status InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=new QNode;
p->next=NULL;
return OK;
}
🌹链栈的入队
🔺实现原理
💬 代码演示
Status EnQueue(LinkQueue &Q,ElemType e)
{
p=new QNode; //为入队元素分配结点空间,用指针p指向
p->data=e; //将新结点数据域置为e
p->next=NULL;
Q.rear->next=p; //将新结点插入到队尾
Q.rear=p; //修改队尾指针为p
return OK;
}
🌹链栈的出队
🔺实现原理
💬 代码演示
Status DeQueue(LinkQueue &Q,ElemType &e)
{
if(Q.front==Q.rear) //若队列为空,返回ERROR
return ERROR;
QNode *p=Q.front->next; //保留头元素空间,以备释放
Q.front->next=p->next; //修改头指针的指针域,指向下一结点
if(Q.rear==p) //判断出队元素是否是最后一个元素,若是,将队尾指针重新赋值,指向头结点
Q.rear=Q.front;
delete p; //释放原队头元素的空间
return OK;
}