队列定义
队列,一种特殊的线性表,乍一看总觉得和栈有那么千丝万缕的联系。事实上,队列的确与栈非常类似,但它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
循环队列–队列的顺序表示与实现
就是与顺序表对应的队列类型,使用一组连续的存储单元依次存放队列从头到尾的元素,同时使用两个整型变量:front(头指针)与rear(尾指针)分别指示队首元素和队尾元素。
循环队列存储结构表示
typedef int QElemType;
//队列的顺序存储结构
#define MAXSIZE 100 //队列可能达到的最大长度
typedef struct
{
QElemType *base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
}SqQueue;
通常为了方便起见,约定:初始化创建空队列时,令front=rear=0,每当插入新的队列尾元素时,尾指针rear++;每当删除队列头元素时,头指针front++。而当rear满溢时则通过“模”运算(rear=(rear+1)%MAXSUIZE)来使rear回到起点,即形成首尾相连的循环队列。
头、尾指针以及队列元素之间的关系不变,只是在循环队列中,头、尾指针“依环状增1”的操作可用“模”运算来实现。
队空与队满的判断条件(通常)
1 少用一个元素空间
即当队列空间大小为m时,有m-1个元素就认为是队满
队空条件: Q.front ==Q.rear;
队满条件: (Q.rear+1)%MAXQSIZE ==Q.front;
2 多设一个元素空间
原理与上面差不多,就是还剩一个空闲空间时便认为队满
条件与上相同
循环队列的初始化
Status InitQueue(SqQueue& Q)
{//构建一个空队列Q
Q.base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXQSIZE的数组空间
Q.front = Q.rear = 0; //头指针和尾指针置为0,队列为空
return 1;
}
求循环队列长度
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
循环队列入队
Status EnQueue(SqQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素
if ((Q.rear + 1) % MAXQSIZE == Q.front) //判断是否队满
return 0;
Q.base[Q.rear] = e; //插入元素
Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针加1
return 1;
}
循环队列出队
Status DeQueue(SqQueue& Q, QElemType& e)
{//删除Q的队头元素,用e返回其值
if (Q.rear == Q.front) //判断队空
return 0;
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE; //队头指针加1
return 1;
}
取队头元素
QElemType GetHead(SqQueue Q)
{//返回Q的队头元素,不修改头指针
if (Q.rear != Q.front) //判断队空
return Q.base[Q.front]; //返回队头元素值
}
链队–队列的链式表示和实现
链队是指采用链式存储结构实现的队列。通常链队用单链表来表示。为方便起见一般给链队添加一个头结点,并令头指针始终指向头结点。
链队的操作即为单链表插入和删除操作的特殊情况,只是通过修改尾指针和头指针来进行。
链队的初始化
#define Status int
typedef int QElemType;
//队列的顺序存储结构
#define MAXQSIZE 100 //队列可能达到的最大长度
typedef struct QNode //结点定义
{
QElemType data;
struct QNode* next;
}QNode,*QueuePtr;
typedef struct //队列定义
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
链队的初始化
Status InitQueue(LinkQueue& Q)
{//构造一个空队列Q
Q.front=Q.rear = new QNode; //生成新结点作为头结点,队头和队尾指针指向此节点
Q.front->next = NULL; //头结点的指针域置空
return 1;
}
链队的入队
Status EnQueue(LinkQueue& Q, QElemType e)
{//插入元素e作为Q的新队尾元素
QNode *p = new QNode; //分配空间
p->data = e; //赋值
p->next = NULL;
Q.rear->next = p; //插入队列
Q.rear = p; //修改队尾指针
return 1;
}
链表的出队
Status DeQueue(LinkQueue& Q, QElemType e)
{//删除Q队头元素并用e返回其值
if (Q.front == Q.rear)
return 0; //判断队空
QNode *p = Q.front->next; //p指向队头元素
e = p->data; //用e保存队头元素值
Q.front->next = p->next; //出队
if (Q.rear == p) //如果出队后空队,队尾指针指向头结点
Q.rear = Q.front;
delete p; //释放空间
return 1;
}
取链表头元素
QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改头指针
if (Q.rear != Q.front) //判断队空
return Q.front->next->data; //返回队头元素值
}