六。队列的相关概念

​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