相关术语
队列(queue):是一种先进先出(FIFO,First In First Out)的线性表,在表的一端插入(表尾),在另一端(表头)删除
eg
Q=(
a
1
a_1
a1,…,
a
n
a_n
an),其中
a
1
a_1
a1为队头,
a
n
a_n
an为队尾
插入元素称为入队;删除元素称为出队
队列的存储结构为链队或顺序队(常用循环顺序队)
| 队列 | ------ |
|---|---|
| 定义 | 只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表 |
| 逻辑结构 | 与线性表相同,仍为一对一关系 |
| 存储结构 | 顺序队或链队,以循环顺序队列更常见 |
| 运算规则 | 只能在队首和队尾进行运算,且访问结点时依照先进先出(FIFO)的原则 |
| 实现方式 | 关键是掌握入队和出队操作,具体实现依存储结构的不同而不同 |
抽象数据类型定义
ADT Queue{
数据对象 D={
a
i
a_i
ai |
a
i
a_i
ai∈ElemSet,i=1,2,…,n,n>=0}
数据关系:R={<
a
i
−
1
,
a
i
a_{i-1},a_i
ai−1,ai> |
a
i
−
1
,
a_{i-1},
ai−1,
a
i
a_i
ai∈D,i=2,…,n}
基本操作:
InitQueue(&Q)
DestroyQueue(&Q)
ClearQueue(&Q)
QueueLength(Q)
GetHead(Q,&e)
EnQueue(&Q,e)
DeQueue(&Q,&e)
…
}ADT Queue
表现和操作的实现
顺序队
//顺序队的结构类型定义
#define MAXSIZE 100
typedef struct{
QElemType *base; //初始化时动态分配存储空间,也可以QElemType base[MAXSIZE];
int front,rear;
}SqQueue;
SqQueue Q;
//空队
Q.front==Q.rear;
//入队
Q.base[rear]=x;Q. rear++;
//出队
x=Q.base[front];Q.front++;
Q.rear==MAXSIZE时,发生溢出
若Q.front==0&&Q.rear==MAXSIZE,再入队——真溢出
若Q.front!=0&&Q.rear==MAXSIZE,再入队——假溢出
//解决假溢出的办法,循环顺序队
Q.base[Q.rear]=x;
Q.rear=(Q.rear+1)%MAXSIZE; //入队
x=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;//出队
// 队空和队满的判断
Q.rear==Q.front;此时可能队空也可能队满
解决方案:另设一个变量记录元素个数或者少用一个元素空间,这里介绍第二种方法
if((Q.rear+1)%MAXSIZE==Q.front) //队满
if(Q.rear==Q.front) //队空
队列的初始化
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXSIZE];
if(!Q.base) exit(OVERFLOW);
Q.front=0;Q.rear=0;
return OK;
}
求队列的长度
int QueueLength(SqQueue Q){
return (Q.rear+MAXSIZE-Q.front)%MAXSIZE;
}
入队
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1)%MAXSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return OK;
}
出队
Status DeQueue(SqQueue &Q,QElemType &e){
if(Q.rear==Q.front) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return OK;
}
取队头元素
QElemType GetHead(SqQueue Q){
if(Q.front!=Q.rear) return Q.base[Q.front];
}
链队
//链队的结构类型定义
typedef struct Qnode{ //结点的数据类型定义
QElemType data;
struct Qnode *next;
}Qnode,*QueuePtr;
typedef struct{
QueuePtr front,rear;
}LinkQueue;
LinkQueue Q;
链队的初始化
Status InitQueue(LinkQueue &Q){
Q.front=new Qnode; //带头结点
if(!Q.front) exit(OVERFLOW);
Q.rear=Q.front;Q.front->next=NULL;
return OK;
}
销毁链队
Status DestroyQueue(LinkQueue &Q){
QueuePtr p;
while(Q.front){
p=Q.front;Q.front=Q.front->next;delete p;}
Q.rear=NULL;
return OK;
}
入队
Status EnQueue(LinkQueue &Q,QElemType e){
QueuePtr p=new Qnode;
p->data=e;
Q.rear->next=p;p->next=NULL;Q.rear=p;
return OK;
}
出队
Status DeQueue(LinkQueue &Q,QElemType &e){
if(Q.rear==Q.front) return ERROR;
QueuePtr p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(p==Q.rear) Q.rear=Q.front;
delete p;
return OK;
}
170万+

被折叠的 条评论
为什么被折叠?



