顺序循环队列
- 思维导图:
- 队列的定义:
- 队列的特点
- 队列的基本操作:
- 顺序循环队列基本操作的实现:
- 情况一:rear和front指向同一位置时
- 队列定义:
- 队列初始化:
- 入队:
- 出队:
- 队列判空:
- 返回队头元素:
- 情况二:rear在front后面
- 队列定义:
- 队列初始化:
- 入队:
- 出队:
- 队列判空:
- 返回队头元素:
思维导图:
队列的定义:
队列依旧是一种特殊的线性表。但是它只允许在一端进行插入,在另一端进行删除操作。
队列的特点
FIFO:first in first out
队列的基本操作:
初始化队列:InitQueue(&Q)
销毁队列:DestoryQueue(&L)
入队:EnQueue(&Q,x)
出队:DeQueue(&Q,&x)
读队头元素:GetHead(s,&x)
判空栈:QueueEmpty(S)
顺序循环队列基本操作的实现:
情况一:rear和front指向同一位置时
队列定义:
1.用牺牲一个节点为代价判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
}SqQueue;
2.用size标记判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
int size; //size为0则空,size为MaxSize则满
}SqQueue;
3.用tag标记判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
int tag; //入队为1,出队为0
}SqQueue;
队列初始化:
1.用牺牲一个节点为代价判断空和满
void InitQueue(SqQueue &Q){
Q.rear = Q.front = 0;
}
2.用size标记判断空和满
void InitQueue(SqQueue &Q){
Q.rear = Q.front = 0;
size = 0;
}
3.用tag标记判断空和满
void InitQueue(SqQueue &Q){
Q.rear = Q.front = 0;
tag = 0;
}
入队:
1.用牺牲一个节点为代价判断空和满
ps: 计算队列元素个数:
(rear+MaxSize-front) % MaxSize
eg:(2+10-3) % 10 = 9(上图)
bool EnQueue(SqQueue &Q,int x){
if((Q.rear+1) % MaxSize == Q.front)
return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
return true;
}
2.用size标记判断空和满
bool EnQueue(SqQueue &Q,int x){
if(Q.size == MaxSize)
return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
size ++;
return true;
}
3.用tag标记判断空和满
bool EnQueue(SqQueue &Q,int x){
if(Q.front == Q.rear && tag == 1)
return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
tag = 1;
return true;
}
出队:
1.用牺牲一个节点为代价判断空和满
bool DeQueue(SqQueue &Q,int &x){
if(Q.rear == Q.front)
return false;
x = Q.data[Q.front];
Q.front = (Q.front + 1) & MaxSize;
return true;
}
2.用size标记判断空和满
bool DeQueue(SqQueue &Q,int &x){
if(Q.size == 0)
return false;
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
size --;
return true;
}
3.用tag标记判断空和满
//每次删除操作成功时都令tag=0,只有删除操作才可能导致队空
//每次插入操作成功时都令tag=1,只有插入操作才可能导致队满
bool EnQueue(SqQueue &Q,int x){
if(Q.front == Q.rear && tag == 0)
return false;
x = Q.data[Q.rear];
Q.front= (Q.front+ 1) % MaxSize;
tag = 0;
return true;
}
队列判空:
1.用牺牲一个节点为代价判断空和满
bool QueueEmpty(SqQueue Q){
if(Q.rear == Q.front)
return true;
else
return false;
}
2.用size标记判断空和满
bool QueueEmpty(SqQueue Q){
if(Q.size == MaxSize)
return true;
else
return false;
}
3.用tag标记判断空和满
bool QueueEmpty(SqQueue Q){
if(Q.front == Q.rear && tag == 1)
return true;
else
return false;
}
返回队头元素:
1.用牺牲一个节点为代价判断空和满
bool GetHead(SqQueue &Q,int &x){
if(Q.rear == Q.front)
return false;
x = Q.data[Q.front];
return true;
}
2.用size标记判断空和满
bool GetHead(SqQueue &Q,int &x){
if(Q.size == 0)
return false;
x = Q.data[Q.front];
return true;
}
3.用tag标记判断空和满
bool GetHead(SqQueue &Q,int &x){
if(Q.front == Q.rear && tag == 0)
return false;
x = Q.data[Q.front];
return true;
}
情况二:rear在front后面
队列定义:
1.用牺牲一个节点为代价判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
}SqQueue;
2.用size标记判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
int size;
}SqQueue;
3.用tag标记判断空和满
typedef struct{
int data[MaxSize];
int front,rear;
int tag;
}SqQueue;
队列初始化:
1.用牺牲一个节点为代价判断空和满
void InitQueue(SqQueue &Q){
Q.front = 0;
Q.rear = (Q.front - 1) % MaxSize;
}
2.用size标记判断空和满
void InitQueue(SqQueue &Q){
Q.front = 0;
Q.rear = (Q.front - 1) % MaxSize;
int size;
}
3.用tag标记判断空和满
void InitQueue(SqQueue &Q){
Q.front = 0;
Q.rear = (Q.front - 1) % MaxSize;
int tag;
}
入队:
1.用牺牲一个节点为代价判断空和满
bool EnQueue(SqQueue &Q,int x){
if((Q.rear+2) % MaxSize == Q.front)
return false;
Q.rear = (Q.rear + 1) % MaxSize;
Q.data[Q.rear] = x;
return true;
}
2.用size标记判断空和满
bool EnQueue(SqQueue &Q,int x){
if(Q.size == MaxSize)
return false;
Q.rear = (Q.rear + 1) % MaxSize;
Q.data[Q.rear] = x;
size ++;
return true;
}
3.用tag标记判断空和满
bool EnQueue(SqQueue &Q,int x){
if((Q.rear+1) % MaxSize == Q.front && tag == 1)
return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MaxSize;
tag = 1;
return true;
}
出队:
1.用牺牲一个节点为代价判断空和满
bool DeQueue(SqQueue &Q,int &x){
if((Q.rear+1) % MaxSize == Q.front)
return false;
Q.front = (Q.front + 1) & MaxSize;
x = Q.data[Q.front];
return true;
}
2.用size标记判断空和满
bool DeQueue(SqQueue &Q,int &x){
if(Q.size == 0)
return false;
Q.front = (Q.front + 1) % MaxSize;
x = Q.data[Q.front];
size --;
return true;
}
3.用tag标记判断空和满
//每次删除操作成功时都令tag=0,只有删除操作才可能导致队空
//每次插入操作成功时都令tag=1,只有插入操作才可能导致队满
bool EnQueue(SqQueue &Q,int x){
if((Q.rear+1) % MaxSize == Q.front && tag == 0)
return false;
Q.front= (Q.front+ 1) % MaxSize;
x = Q.data[Q.rear];
tag = 0;
return true;
}
队列判空:
1.用牺牲一个节点为代价判断空和满
bool QueueEmpty(SqQueue Q){
if((Q.rear+1) % MaxSize == Q.front)
return true;
else
return false;
}
2.用size标记判断空和满
bool QueueEmpty(SqQueue Q){
if(Q.size == MaxSize)
return true;
else
return false;
}
3.用tag标记判断空和满
bool QueueEmpty(SqQueue Q){
if((Q.rear+1) % MaxSize == Q.front && tag == 0 )
return true;
else
return false;
}
返回队头元素:
1.用牺牲一个节点为代价判断空和满
bool GetHead(SqQueue &Q,int &x){
if((Q.rear+1) % MaxSize == Q.front)
return false;
x = Q.data[Q.front];
return true;
}
2.用size标记判断空和满
bool GetHead(SqQueue &Q,int &x){
if(Q.size == 0)
return false;
x = Q.data[Q.front];
return true;
}
3.用tag标记判断空和满
bool GetHead(SqQueue &Q,int &x){
if((Q.rear+1) % MaxSize == Q.front && tag == 0)
return false;
x = Q.data[Q.front];
return true;
}