前言
栈和队列的定义和基本操作(初始化入栈出栈,入队出队)
顺序栈、链栈
顺序队列、循环队列、链队列
栈
定义:
- 先进后出(LIFO)
- 只能在表的一端插入或删除的线性表。
- 表的尾端为栈顶(top),头端为栈底(base)
- 没有元素的栈称为空栈
顺序栈
顺序栈的表示
- 地址连续的存储单元存放自栈底到栈顶的元素。栈底元素存在低地址
创建栈表
typedef SElemType int;
typedef struct
{
//栈底
SElemType *base;
//栈顶
SElemType *top;
//栈容量
int StackSize;
}SqStack;
SqStack S;
顺序栈的基本操作
- 初始化
int MAXSIZE = 100;
bool InitStack(SqStack &S)
{
//创建栈空间
S.base= new SElemType Stack[MAXSIZE];
if (!S.base) return false;
S.StackSize = MAXSIZE;
S.top=S.base;
return true;
}
- 入栈
bool Push(SqStack &S,SElemType e)
{
if(S.top-S.base==S.StackSize) return false;
*S.top=e;
S.top++;
return true;
}
- 出栈
bool Pop(SqStack &S,SElemType &e)
{
if(S.base==S.top) return false;
S.top--;
e= *S.top;
return true;
}
链栈
链栈的表示
与链表的形式相同,链栈的元素也是通过结点的指针相关联
栈顶指针就是头指针
插入和删除操作在栈顶完成,所以不需要头结点访问整个链栈
几乎不存在满栈的情况
创建链栈
typedef SElemType int;
typedef struct StackNode
{
//数据域
int data;
//指针域
struct StackNode *next;
}StackNode,*LinkStack
链栈的基本操作
- 初始化
void InitLinkStack(LinkStack &S)
{
S->next=null;
}
- 求链栈的长度
int StackLength(LinkStack &S)
{
int len=0;
StackNode *cur=S;
while(cur!=NULL)
{
len++;
cur=cur->next;
}
return len;
}
- 入栈
void push(LinkStack &S,SElemType e)
{
//构造一个结点p,并给结点的数据域赋值
StackNode *p=new StackNode;
p->data=e;
p->next=NULL;
if(S==NULL)
{
//如果栈为空,那直接将栈顶指针修改为p
S=p;
}
else
{
//如果不为空,就先将结点p放在栈顶结点前面,再改变栈顶指针
p->next=S;
S=p;
}
}
- 出栈
bool pop(LinkStack &S,SElemType &e)
{
StackNode *p=new StackNode;
if(S==NULL) return false;
else
{
//栈不为空,去除栈顶元素,栈顶指针后移一位,删除栈顶结点
p=s;
e=p->data;
s=s->next;
delete p;
}
return true;
}
共享栈
有两个相同类型的栈时,采用共享栈最大限度地利用空间进行操作;共享栈既可以使用自己的空间,也可以使用对方的空间
0 MAXSIZE-1
====================== ======================
^ ^ ^ ^
1号栈底 1号栈顶 2号栈顶 2号栈底
构造共享栈
typedef SElemType int;
typedef struct
{
SElemType s1[MAXSIZE];
SElemType s2[MAXSIZE];
int top1;
int top2;
}SharedStack;
SharedStack S;
共享栈的基本操作
- 判空:
bool isEmpty(SharedStack S)
{
if(S.top1== -1 && S.top2 == MAXSIZE) return true;
return false;
}
- 判满:
bool isFull(SharedStack S)
{
if(S.top1+1 == S.top2) return true;
return false;
}
- 进栈:
//1号栈入栈
bool Push1(SharedStack &S,SElemType e)
{
if(isFull(S)) return false;
S.top1 ++;
S.s1[S.top1]=e;
return true;
}
//2号栈入栈
bool Push2(SharedStack &S,SElemType e)
{
if(isFull(S)) return false;
S.top2 --;
S.s2[S.top2]=e;
return true;
}
- 出栈:
//1号栈出栈
bool Pop1(SharedStack &S,SElemType &e)
{
if(isFull(S)) return false;
e=S.s1[S.top1];
S.top1 --;
return true;
}
//2号栈出栈
bool Pop1(SharedStack &S,SElemType &e)
{
if(isFull(S)) return false;
e=S.s2[S.top2];
S.top2 ++;
return true;
}
队列
定义:
先进先出(FIFO)的线性表,在表的一端插入,另一端删除
顺序队列
构造顺序队列
typedef QElemType int;
typedef struct
{
int MAXSIZE=100;
QElemType front;
QElemType rear;
QElemType data[MAXSIZE];
}SQueue;
SQueue SQ;
顺序栈的基本操作
- 初始化
bool InitSQueue(SQueue &SQ)
{
if(!SQ.data) return false;
SQ.rear=SQ.front=0;
return true;
}
- 入队
bool EnQueue(SQueue &SQ,QElemType e)
{
if(SQ.rear==SQ.MAXSIZE-1) return false;
SQ.data[rear]=e;
rear++;
return true;
}
- 出队
bool DeQueue(SQueue &SQ,QElemType &e)
{
if(SQ.rear==0) return false;
e=SQ.data[front];
front++;
return true;
}
- 打印队列
bool PrintQueue(SQueue &SQ)
{
if(SQ.rear==0) return false;
int qsize=SQ.rear-SQ.front;
printf("打印队列:\n");
for(int i=0;i<qsize;i++)
{
if(i==0) printf("队首|");
printf("%d ",SQ.data[i]);
if(i==qsize-1) printf("|队尾");
}
return true;
}
循环队列
定义
循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
构造循环队列
typedef QElemType int;
typedef struct
{
int MAXSIZE=100;
QElemType front;
QElemType rear;
QElemType data[MAXSIZE];
}CcQueue;
CcQueue CQ;
循环队列的基本操作
- 初始化
bool InitCcQueue(CcQueue &CQ)
{
if(!SQ.data) return false;
CQ.rear=CQ.front=0;
return true;
}
- 判断队列长度
int getLength(CcQueue &CQ)
{
return (CQ.rear+CQ.MAXSIZE-CQ.front)%CQ.MAXSIZE;
}
- 入队
bool EnQueue(CcQueue &CQ,QElemType e)
{
//判满
if((CQ.rear+1)%MAXSIZE==CQ.front) return false;
CQ.data[CQ.rear]=e;
CQ.rear=(CQ.rear+1)%CQ.MAXSIZE;
return true;
}
- 出队
bool DeQueue(CcQueue &CQ,QElemType &e)
{
//判空
if(CQ.rear==CQ.front) return false;
CQ.front=(CQ.front+1)%CQ.MAXSIZE;
e=CQ.data[CQ.front];
return true;
}
- 打印队列
bool PrintQueue(SQueue &SQ)
{
//判空
if(CQ.rear==CQ.front) return false;
int qsize=getLength(SQ);
printf("打印队列:\n");
for(int i=0;i<qsize;i++)
{
if(i==0) printf("队首|");
printf("%d ",CQ.data[i]);
if(i==qsize-1) printf("|队尾");
}
return true;
}
链队列
定义
使用链式存储结构的队列,称为链队列
构造链队列管理结构
//链式队列管理结构
typedef QElemType int;
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
LinkQueue LQ;
创建链队列结点类型
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
链队列的基本操作
- 初始化
bool InitLinkQueue(LinkQueue &LQ)
{
//生成头结点
LQ.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!LQ.front) return false;
//将头结点的指针域置为空
LQ.front->next=NULL;
return true;
}
- 判断队列长度
int getLength(LinkQueue &LQ)
{
int len=0;
QNode *p=LQ.front->next;
while(p)
{
len++;
p=p->next;
}
return len;
}
- 入队
//新元素e 入队
bool EnQueue(LinkQueue &LQ,QElemType e)
{
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) return false;
p.data=e; //新元素存入新结点
LQ.rear->next=p; //将队尾结点与新结点建立连接
p->next=NULL; //新结点的指针域置为空
LQ.rear=p; //队尾指针指向新结点
}
- 出队
bool DeQueue(LinkQueue &LQ,QElemType &e)
{
if(!LQ.front->next) return false;
e=LQ.front->next->data;
LQ.front->next=LQ.front->next->next;
return true;
}
- 打印队列
bool PrintQueue(LinkQueue LQ)
{
if(!LQ.front->next) return false;
QNode *p=LQ.front->next;
while(p)
{
printf("%d ",p->data);
}
return true;
}
、
总结
本文主要介绍了栈和队列的定义和基本操作(初始化入栈出栈,入队出队)
文章到这结束啦,感谢阅读~
如果文章的论述或代码等出现错误,欢迎前来指正!
如果你觉得文章写的还不错,记得点赞收藏评论三连~ ❤