示例图:
定义:只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表 (头删尾插)
存储结构:顺序队,链队
运算规则:先进先出(FIFO)
一:链式队列:
1.存储结构定义:
typedef struct Qnode {
QElemType data;
stuct Qnode *next;
}QNode, *QuenePtr;
typedef struct {
QuenePtr front; // 队头指针
QuenePtr rear; // 队尾指针
} LinkQueue;
2.基本操作:
(1)初始化链对:
Status InitQueue(LinkQueue &q) { //构造空队列q
q.front = q.rear =(QueuePtr)malloc(sizeof(QNode));//队头和队尾指向同一个区域
If (!q.front) exit (OVERFLOW); //存储分配失败
q.front ->next = NULL;//队头指向的区域为空
return OK;
}// InitQueue;
(2)销毁队列
Status DestoryQueue(LinkQueue &q) { //销毁队列q
while (q.front)
{
q.rear = q.front -> next;//用q.rear(QuenePtr类型),节省空间
free(q.front);//释放结点
q.front = q.rear;//转移队头指针
}
return OK;
}// DestoryQueue;
(3)入队:
status EnQueue(LinkQueue &Q,ElemType e)
{
p=(QueuePtr)molloc(sizeof(QNode));
if(!p)exit(OVERFLOW);
p->data=e;
p->next=null;
Q.rear->next=p;
Q.rear=p;
return OK;
}
(4)出队(删除队头元素(头结点连接的第一个元素)):
status EnQueue(LinkQueue &Q,EleType &e)
{
if(Q.front==Q.rear)return ERROR;
p=Q.font->next;
e=p.data;
Q.font->next=p->next;
if(p==Q.rear)Q.rear=Q.front;//链队中只有一个元素(还有一个头结点)的情况
free(p);//释放p结点
return OK;
}
二.队列的顺序表示:
1.存储结构类型定义:
Struct Queue
{
ElemType queue[QueueMaxSize];
int front,rear;
};
*队头Q.front总是指向元素,队尾Q.rear总是指向要增加的元素
2.顺序队列可能会遇到下面问题(如图所示):
队满可能会有几种形式:
1).队中有全部元素
2).队中只有上半部分有元素
3).队中没有元素
假上溢:队空间中还有存储单元未使用,但不能再插入元素。
假上溢产生原因:头、尾指针值总是不断改变,导致已使用过的单元无法再使用。
3.可采用以下方式解决:
(1).元素都往队头靠(缺点:浪费时间)
(2).采用循环队列(详解如三)
三.循环队列:
1.存储结构定义:
typedef struct {
QElemType *base; // 动态分配存储空间
int front;
// 头指针,若队列不空,指向队列头元素
int rear;
// 尾指针,若队列不空,指向队列尾元素
的下一个位置
} SqQueue;
2.存在的问题及解决手段:
这样设计之后也存在问题,当队空时,有Q.front=Q.rear;而队满时也是Q.front=Q.rear,故造成冲突
解决方法:
1).在队中设立一个空的存储单元,这样的话队满时就是Q.front=(Q.rear+1)%MaxSize
2).增加一个标志量Q.flag,当初始化循环队列时(队空),Q.flag=0;当有元素且Q.front=Q.rear时
3).设置一个标志量用来记录元素的个数,当元素个数为0为队空,当元素个数等于MaxSize时队满
3.基本操作:
(1)初始化空队列:
Status InitQueue(SqQueue &Q) { //构造空队列Q
q.base = (QElemType*) malloc(MAXSIZE*sizeof(QElemType));
If (!q.base) exit (OVERFLOW); //存储分配失败
q.front = q.rear = 0;
return OK;
}//InitQueue;
(2)求队列的长度:
Int QueueLen(SqQueue Q)
{
//求取队列Q的元素个数
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
(3)入队:
Status InsertQueueLen(SqQueue &Q,QElemType e){
//元素e入队列Q
if ((Q.rear + 1) % MAXSIZE == Q.front)//如果队满,则就不能入队
return ERROR;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXSIZE;
return OK;
}
(4).出队:
int DeQueue ( SeqQueue &Q, QElemType &e ) {
if ( QueueEmpty (Q) ) return 0;
e = Q.base[Q.front];
Q.front = ( Q.front+1) % MAXQSIZE;
return OK;
}