typedef struct SqQueue{
int data[maxSize];
int front; // 队头指针
int rear; // 队尾指针
}SqQueue;
void initQueue(SqQueue &qu){
qu.front = qu.rear = 0; // 队首和队尾指针重合
}
int isEmpty(SqQueue qu){
if(qu.front == qu.rear){
return 1; // 头指针等于尾指针,队空
}else{
return 0; // 否则队不空
}
}
注意:队空返回 1 ,队列不空返回 0。
int enQueue(SqQueue &qu , int x){
if(qu.rear == maxSize){ // 尾指针等于最大空间,队满
return 0;
}
// 队尾进元素
qu.rear += 1;
qu.data[qu.rear] = x; // 存入元素
return 1;
}
注意:入队需要判断队满,队满的条件是队尾指针等于数组最大空间数,但是这样,队头出元素会浪费很多时间
int deQueue(SqQueue &qu , int &x){
if(qu.front == qu.rear){ // 队空,出队失败
return 0;
}
x = qu.data[qu.front]; // 元素赋值
qu.front -= 1; // 队头指针移动
return 1;
}
概述:循环队列是由普通队列的演变而来,是因为普通队列在出队操作后,队列的头部空间就无法利用,导致空间的浪费,为了解决这一问题,循环队列产生了,循环队列就是将队列的头尾相连,形成一个环状结构,这样就可以循环利用头部空间避免浪费。
循环队列的特点
// 队空
front == rear; // 头指针和尾指针 相等
// 队满
front = (rear + 1)%maxSize;
rear = (front -1 + maxSize)%maxSize;
// 入队、出队,均先移动指针
rear = (rear + 1)%maxSize;
front = (front + 1)%maxSize;
typedef struct Queue{
int data[maxSize];
int front; // 队头指针
int rear; // 队尾指针
}Queue;
void initQueue(SqQueue &qu){
qu.front = qu.rear = 0; // 队首和队尾指针重合
}
int isEmpty(SqQueue qu){
if(qu.front == qu.rear){ // 队空
return 1;
}else{ // 队满
return 0;
}
}
int enQueue(SqQueue &qu , int x){
if(qu.front == (qu.rear + 1)%maxSize){
return 0; // 队满,进队失败
}
/*队尾进元素,队头出元素*/
qu.rear = (qu.rear + 1)%maxSize; // 移动尾指针,指向空位置
qu.data[qu.rear] = x; // 存入元素
return 1;
}
int deQueue(SqQueue &qu , int &x){
if(qu.front == qu.rear){
return 0; // 队空,出队失败
}
qu.front = (qu.front + 1)%maxSize; // 移动头指针,指向出队元素
x = qu.data[qu.front]; // 元素赋值
return 1;
}
// 队列结点
typedef struct QNode{
int data;
struct QNode *next;
}QNode;
// 链队
typedef struct LiQueue{
QNode *front; // 队头指针
QNode *rear; // 队尾指针
}LiQueue;
void initQueue(LiQueue *&lqu){
lqu = (LiQueue *)malloc(sizeof(LiQueue));
lqu->front = lqu->rear = NULL;
}
int isEmpty(LiQueue *lqu){
if(lqu->front == NULL || lqu->rear == NULL){
return 1;
}else{
return 0;
}
}
void enQueue(LiQueue *lqu , int x){
QNode *p;
p = (QNode *)malloc(sizeof(QNode)); // 创建一个新结点
p->data = x;
p->next = NULL;
/*如果队列为空,则插入结点是首元结点,头、尾指针都指向*/
if(lqu->front == NULL || lqu->rear == NULL){
lqu->front = p;
lqu->rear = p;
}else{ // 新结点链接到队尾即可
lqu->rear->next = p;
lqu->rear = p;
}
}
注意:单链表入队,无需判断队满
int deQueue(LiQueue *lqu , int &x){
QNode *p;
if(lqu->front == NULL || lqu->rear == NULL){
return 0; // 队空不能出队
}else{
p = lqu->front; // 减少冗余
if(lqu->front == lqu->rear){ // 只剩下首元结点
// p = lqu->front;
lqu->front = lqu->rear = NULL; // 指针指向,删除结点
}else{
// p = lqu->front;
lqu->front = p->next;
}
}
x = p->data;
free(p); // 释放结点
return 1;
}
注意:出队需要判断队空,链队入队和出队要注意 第一个元素的入队 和 最后一个元素的出队
/* 循环队列的类型定义 */
typedef struct cyQueue{
int data[maxSize]; // maxSize 为已定义的常量
int front,rear;
}cyQueue;
/* 从队头删除和队尾插入的算法 */
/*队头删除元素*/
int deQueue(cyQueue &cqu , int &x){
if(cqu.front == cqu.rear){ // 队空
return 0;
}
cqu.front = (cqu.front + 1)%maxSize; // 指针移动,移到第一个删除元素
x = cqu.data[cqu.front];
return 1;
}
/*队尾进入元素*/
int enQueue(cyQueue &cqu , int x){
if(cqu.front == (cqu.rear + 1)%maxSize){ // 队满
return 0;
}
cqu.rear = (cqu.rear + 1)%maxSize; // 指针移动,移动到空位置插入元素
cqu.data[cqu.rear] = x;
return 1;
}
/* 从队尾删除和队头插入的算法 */
/*队尾删除元素*/
int deQueue(cyQueue &cqu , int &x){
if(cqu.front == cqu.rear){ // 队空
return 0;
}
x = cqu.data[cqu.rear]; // 先赋值
cqu.rear = (cqu.rear - 1 + maxSize)%maxSize; // 尾指针移动
return 1;
}
/*队头插入元素*/
int enQueue(cyQueue &cqu , int x){
if(cqu.rear == (cqu.front -1 + maxSize)%maxSize){
return 0; // 队满
}
cqu.data[cqu.front] = x;
cqu.front = (cqu.front - 1 + maxSize)%maxSize; // 头指针移动
return 1;
}
注意:头插尾山,是逆时针从大到小的顺序
/*入队列*/
void enQueue(LNode *&rear , int x){ // rear 指针发生改变
LNode *s = (LNode *)malloc(sizeof(LNode));
s->next = NULL;
s->data = x; // x 给结点赋值
/*头插法,将新结点插入循环链表尾部*/
s->next = rear->next;
rear->next = s;
rear = rear->next; // 指针后移
}
/*出队列:方式一*/
int deQueue(LNode *&rear , int &x){
LNode *p;
/*出队列判断队空*/
if(rear->next == rear){ // 只有头结点
return 0;
}else{
p = rear->next->next;
if(rear->next->next == rear){ // 只有首元结点,特殊处理
rear = rear->next;
}else{ // 不只有首元结点
rear->next->next = p->next;
}
x = p->data;
free(p);
return 1;
}
}
/*出队列:方式二*/
int deQueue(LNode *&rear , int &x){
LNode *p;
if(rear->next == rear){
return 0;
}else{
p = rear->next->next; // p 指向首元结点
rear->next->next = p->next; // 删除结点
x = p->data;
if(p == rear)
rear = rear->next;
free(p);
return 1;
}
}
void level(BTNode *bt){
/*定义队列,并初始化*/
BTNode *que[maxSize];
int front , rear;
front = rear = 0;
BTNode *p;
if(bt != NULL){
rear = (rear + 1)%maxSize;
que[rear] = bt;
while(front != rear){ // 队列不空
front = (front + 1)%maxSize;
p = que[front];
visit(p); // 访问 p
if(p->lChild != NULL){ // 左子书进入队列
que[(rear + 1)%maxSize] = p->lChild;
}
if(p->rChild != NULL){ // 右子树进入队列
que[(rear + 1)%maxSize] = p->rChild;
}
}
}
}