数据结构 -第4周栈和队列第3讲-队列的定义和顺序队

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
x=qu->data[qu->front]; qu->count--; return true; } }
//出队运算算法 //队空下溢出
//队头循环增1 //元素个数减1
第 29 页 共 32 页
第 30 页 共 32 页
注意:
第 31 页 共 32 页
━━本讲完━━
第 32 页 共 32 页
front=(front+1)%MaxSize
第 18 页 共 32 页
2
3
1
40
rear
b c 3 21a
40
front rear
(a)空队
源自文库
front
(b)a、b、c进队
rear
b
c 3 21
40
front rear
front
2
3
1
40
(c)出队一次
(d)出队2次
第 19 页 共 32 页
现在约定rear=front为队空,以下两种情况都满足该条件:
第 21 页 共 32 页
环形队列的4要素:
队空条件:front = rear 队满条件:(rear+1)%MaxSize = front 进队e操作:rear=(rear+1)%MaxSize; 将e放在rear处 出队操作:front=(front+1)%MaxSize; 取出front处元素e;
qu->data[rear]=x;
qu->count++;
//元素个数增1
return true;
}
}
第 28 页 共 32 页
bool DeQueue(QuType *&qu,ElemType &x) { if (qu->count==0)
return false; else { qu->front=(qu->front+1)%MaxSize;
void InitQueue(SqQueue *&q) { q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=q->rear=-1; }
4 3 2 1 0 rear front
第 11 页 共 32 页
(2)销毁队列DestroyQueue(q)
释放队列q占用的存储空间。
原来如此,简 单!
当rear = 4时,下一步 到位置0,可以进队
第 17 页 共 32 页
环形队列:
c3
4
d
rear
b
2 1
0
a
front
实际上内存地址一定是连续的,不可能是环形的,这里是 通过逻辑方式实现环形队列,也就是将rear++和front++改为:
rear=(rear+1)%MaxSize
出队 队头
队列示意图
进队 队尾
第 2 页 共 32 页
队列的主要特点是先进先出,所以又把队列称为先进先出表。 例如:
假如5个人 过独木桥
只能按上桥的 次序过桥
这里独木桥就是一个队列
第 3 页 共 32 页
队列抽象数据类型=逻辑结构+基本运算(运算描述) 队列的基本运算如下:
InitQueue(&q):初始化队列。构造一个空队列q。 DestroyQueue(&q):销毁队列。释放队列q占用的存储空间。 QueueEmpty(q):判断队列是否为空。若队列q为空,则返回真;否
0
出队一个元素b
rear front
第 15 页 共 32 页
4 d3 c2
1 0
2、环形队列(或循环队列)中实现队列的基本运算
rear front
c4 b3 a2
1
0
还有两个位置, 为何不能进队?
这 是 因 为 采 用 rear==MaxSize-1 作 为 队 满 条 件 的 缺 陷 。 当 队满条件为真时,队中可能还有若干空位置。
//队满上溢出
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
空队:
rear front
4 3 元素a进队
2
1
0
rear
front
第 14 页 共 32 页
4 3 2 1
a0
(5)出队列deQueue(q,e)
若队列q不空,将队首指针front循环增1,并将该位置的元素值赋给e。
则返回假。 enQueue(&q,e):进队列。将元素e进队作为队尾元素。 deQueue(&q,&e):出队列。从队列q中出队一个元素,并将其值赋
给e。
第 4 页 共 32 页
第 5 页 共 32 页
既然队列中元素逻辑关系与线性表的相同,队列可以采用与 线性表相同的存储结构。
队列
逻辑结构
这种溢出并不是真正的溢出,称为假溢出。
第 16 页 共 32 页
解决方案
把数组的前端和后端连接起来,形成一个环形的顺序表,即
把存储队列元素的表从逻辑上看成一个环,称为环形队列或循环
队列。 例 rear 如
front
c4 b3 a2
1
0
b3
4
c
a
2 1
0
front
当rear = 4时,不能 再进队
rear
队空条件:front = rear 队满条件:rear = MaxSize-1 元素e进队:rear++; data[rear]=e; 元素e出队:front++; e=data[front];
第 10 页 共 32 页
1、 顺序队中实现队列的基本运算
(1)初始化队列InitQueue(q)
构造一个空队列q。将front和rear指针均设置成初始状态即-1值。
3.2.1 队列的定义
队列简称队,它也是一种运算受限的线性表。
线性表
端点1
端点2
队列只能选取一个端点进行插入操作,另一个端点进行 删除操作
第 1 页 共 32 页
队列的几个概念
把进行插入的一端称做队尾(rear)。 进行删除的一端称做队首或队头(front)。 向队列中插入新元素称为进队或入队,新元素进队后就成为新 的队尾元素。 从队列中删除元素称为出队或离队,元素出队后,其后继元素 就成为队首元素。
在环形队列中,实现队列的基本运算算法与非环形队列类似,只 是改为上述4要素即可。
第 22 页 共 32 页
【例3-5】对于环形队列来说,如果知道队头指针和队列 中元素个数,则可以计算出队尾指针。也就是说,可以用队列 中元素个数代替队尾指针。
设计出这种环形队列的初始化、入队、出队和判空算法。
第 23 页 共 32 页
顺序队
链队
存储结构
第 6 页 共 32 页
3.2.2 队列的顺序存储结构及其基本运算的实现
顺序队类型SqQueue定义如下:
typedef struct { ElemType data[MaxSize];
int front,rear; //队首和队尾指针 } SqQueue;
因为队列两端都在变化,所以需要两个指针来标识队列的 状态。
return(q->front==q->rear); }
第 13 页 共 32 页
(4)进队列enQueue(q,e)
若队列不满,将队尾指针rear循环增1,然后将元素添加到该位置。
bool enQueue(SqQueue *&q,ElemType e)
{ if (q->rear==MaxSize-1)
front
4 3 2 1 a0
(c)b、c、 d、e进队
(d)全部出队
rear
e
4
rear front
4
d3
3
c2
2
b1
1
a0
0
front

约定rear总是指向队尾元素
元素进队,rear增1

约定front指向当前队中队头元素的前一位置
元素出队,front增1
当rear=MaxSize-1时不能再进队
{ int rear; if (qu->count==MaxSize)
//临时队尾指针 //队满上溢出
return false;
它是elq一sue个中局不部保变存量该,值队列 { rear=(qu->front+qu->count)%MaxSize;
//求队尾位置
rear=(rear+1)%MaxSize; //队尾循环增1
count=(1-3+MaxSize)=3 count=(1-3+MaxSize)%MaxSize=3
第 24 页 共 32 页
已知front、rear,求队中元素个数count:
count=(rear-front+MaxSize)%MaxSize
已知front、count,求rear:
rear=(front+count)%MaxSize
已知front、rear,求队中元素个数count = ?
MaxSize=5
rear
b
c3
2 1
a
40
front count=(3-0)=3
front
2
3
1c
rear
40
a
b
count=(1-3)=-2
count=rear-front ? count=(3-0+MaxSize)=8 count=(3-0+MaxSize)%MaxSize=3
bool deQueue(SqQueue *&q,ElemType &e) { if (q->front==q->rear) //队空下溢出
return false; q->front++; e=q->data[q->front]; return true; }
rear front
4 d3 c2 b1
//队列中元素个数
} QuType;
该环形队列的4要素:
队空条件:count=0 队满条件:count=MaxSize 进队e操作:rear=(rear+1)%MaxSize; 将e放在rear处 出队操作:front=(front+1)%MaxSize; 取出front处元素e;
注意:这样的环形队列中最多可放置MaxSize个元素。
已知rear、count,求front:
front=(rear-count+MaxSize)%MaxSize
第 25 页 共 32 页
解:依题意设计的环形队列类型如下:
typedef struct
{ ElemType data[MaxSize];
int front;
//队头指针
int count;
第 9 页 共 32 页
队列的各种状态
4 3 2 1 0 rear front
(a)空队
rear front
4 3 2 1 a0
(b)a进队
rear
e4
rear front
4
d3
3
c2
2
b1
1
a0
0
front
(c)b、c、d、 e进队
(d)全部出队
顺序队的4要素(初始时front=rear=-1):
2
3
1
40
front rear
初始状态
front rear
2
3
1
40
进队的所有元素均出队
那么如何设置队满的条件呢?
第 20 页 共 32 页
让rear=front为队空条件,并约定
(rear+1)%MaxSize=front 为队满条件。
进队一个元素时
到达队头,就认为 队满了。
这样做会少放一
个元素,牺牲一个 元素没关系的。
void DestroyQueue(SqQueue *&q) {
free(q); }
第 12 页 共 32 页
(3)判断队列是否为空QueueEmpty(q)
若队列q满足q->front==q->rear条件,则返回true;否则返回false。
bool QueueEmpty(SqQueue *q) {
第 26 页 共 32 页
对应的算法如下:
void InitQueue(QuType *&qu) //初始化队运算算法 { qu=(QuType *)malloc(sizeof(QuType));
qu->front=0; qu->count=0; }
第 27 页 共 32 页
bool EnQueue(QuType *&qu,ElemType x) //进队运算算法
第 7 页 共 32 页
逻辑结构 存储结构
队列 (a1, a2, … ,ai, …, an )
映射
0
f

f+1
r
a1 … an …
data 顺序队的示意图
MaxSize-1

fr
front rear
第 8 页 共 32 页
例如:MaxSize=5
(a)空队
(b)a进队
rear front
4 3 2 1 0 rear
相关文档
最新文档