六。队列的相关概念
1.定义
只能在表的一端进行插入运算,在表的另一端进行删除运算的线性
表(头删尾插)
2.逻辑结构
与同线性表相同,仍为一-对一关系。
3.存储结构
顺序队或链队,以循环顺序队列更常见。
4.运算规则
只能在队首和队尾运算,且访问结点时依照先进先出(FIFO) 的原则。
5.实现方式
关键是掌握入队和出队操作,具体实现依顺序队或链队的不同而不同。
队列的常见应用 ■脱和打印输出:按申请的先后顺序依次输出。 ■多用户系统中,多个用户排成队,分时地循环使用CPU和主存 ■按用户的优先级排成多个队,每个优先级一个队列 ■实时控制系统中,信号按接收的先后顺序依次处理 ■网络电文传输,按到达的时间先后顺序依次进行
ADT Queue{
数据对象: D={aja∈ElemSet,i= .2..nn2.. .
数据关系: R={<a1,a,> |a;,a∈D1=...)约定其中a端为队列头, an 端为队列尾。
基本操作:
InitQueue(&Q)操作结果:构造空队列Q
DestroyQueue(&Q)条件:队列Q已存在;操作结果:队列Q被销毁
ClearQueue(&Q)条件:队列Q已存在;操作结果:将Q清空
Queuel ength(Q)条件:队列Q已存在操作结果:返回Q的元素个数,即队长
GetHead(Q, &e)条件: Q为非空队列操作结果:用e返回Q的队头元素
EnQueue(&Q, e)条件:队列Q已存在操作结果: 插入元素e为Q的队尾元素
DeQueuel(&Q, &e)条件: Q为非空队列操作结果: 删除Q的队头元素,用e返回值
....还有将队列置空、遍历队列等操作....
} ADT Queue
七。顺序队列
队列的顺序表示一用一维数组base[MAXQSIZE]
解决假上溢的方法 - 引入循环队列
1、将队中元素依次向队头方向移动。
缺点:浪费时间。每移动一次,队中元素都要移动。
2、将队空间设想成一个循环的表,即分配给队列的m个存储单元可以循环使用,当rear为maxqsize时,若向量的开始端空着,又可从头使用空着的空间。当front为maxqsize时 ,也是一样。
1.[循环队列的设置]
base[0]接在base[MAXQSIZE -1]之后,若rear+1==M,则令rear=0;
插入元素: Q.base[Q.rear]=x;
Q.rear=(Q.rear+ 1)% MAXQSIZE;
删除元素:x=Q.base[s.front]
Q.front=(Q.front+ 1)% MAXQSIZE
队空: front==rear
队满: (rear+ 1)%MAXQSIZE==front
2.[循环队列的操作]
初始化InitSqQueue(SqQueue Q);
void InitSqQueue(SqQueue Q)
{
Q.base = (struct QElemType *)malloc(MAXQSIZE*sizeof(struct QElemType));
if (Q.base == NULL)
{
printf("%s\n", strerror(errno));
}
Q.front = 0;
Q.rear = 0;
}
SqQueueLenght(SqQueue Q);
int SqQueueLenght(SqQueue Q)
{
return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
DeQueue(SqQueue Q, struct QElemType* e);
void DeQueue(SqQueue Q, struct QElemType* e)
{
if (Q.rear == Q.front)
{
return;
}
else
{
*e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
}
}
EnQueue(SqQueue Q, struct QElemType e);
void EnQueue(SqQueue Q, struct QElemType e)
{
if ((Q.rear + 1) % MAXQSIZE == Q.front)
{
return;
}
else
{
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
}
}
struct QElemType GetHead(SqQueue Q);
struct QElemType GetHead(SqQueue Q)
{
if (Q.front != Q.rear)
return Q.base[Q.front];
}
八。链队
struct QElemType
{
int age;
};
typedef struct Qnode
{
struct QElemType data;//数据域元素的类型
struct Qnode* next;
}Qnode,*QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;
InitQueue(LinkQueue Q);
void InitQueue(LinkQueue Q)
{
Q.front = (QueuePtr)malloc(sizeof(Qnode));
Q.rear = (QueuePtr)malloc(sizeof(Qnode));
if (Q.front == NULL&&Q.rear == 0)
printf("%s\n", strerror(errno));
else
{
Q.front->next = NULL;
}
}
DestroyQueue(LinkQueue Q);
void DestroyQueue(LinkQueue Q)
{
while (Q.front != NULL)
{
Qnode* p = Q.front->next;
free(Q.front);
Q.front = p;
}
}
EnQueue(LinkQueue Q, struct QElemType e);
void EnQueue(LinkQueue Q, struct QElemType e)
{
Qnode* p = (Qnode*)malloc(sizeof(Qnode));
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
}
}
DeQueue(LinkQueue Q, struct QElemType e);
void DeQueue(LinkQueue Q, struct QElemType e)
{
if (Q.rear == Q.front)
return;
else
{
Qnode* p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p) Q.rear = Q.front;
free(p);
}
}
GetHead(LinkQueue Q, struct QElemType* e)
void GetHead(LinkQueue Q, struct QElemType* e)
{
if (Q.front == Q.rear)return;
else
{
*e = Q.front->next->data;
return;
}
}
0