第5章 队列 零基础学数据结构
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.3.2
链式队列的实现
(4)出队操作。 int DeleteQueue(LinkQueue *LQ,DataType *e) { LQNode *s; if(LQ->front==LQ->rear) return 0; else { s=LQ->front->next; *e=s->data; LQ->front->next=s->next; if(LQ->rear==s) LQ->rear=LQ->front; free(s); return 1; } }
5.3.2
链式队列的实现
(5)取队头元素。 int GetHead (LinkQueue LQ,DataType *e) { LQNode *s; if(LQ.front==LQ.rear) return 0; else { s=LQ.front->next; *e=s->data; return 1; } }
a
front
b
c
d
e
f
g
h
rear
front=rear=0
5.2.1
顺序队列的表示
a
front=0
b
c
rear=3
c
front=2 rear=3
5.2.1
顺序队列的表示
顺序队列的类型定义如下: #define QueueSize 40 /*队列的容量*/ typedef struct Squeue{ DataType queue[QueueSize]; int front,rear; /*队头指针和队尾指针*/ }SeqQueue;
队列在杨辉三角中的应用
这节我们主要通过学习杨辉三角在队列的应用。本节 的主要内容包括杨辉三角的性质,构造队列及队列的实现。
1 1 1 1 1 1 1 1 7 6 21 5 15 35 4 10 20 35 3 6 10 15 21 2 3 4 5 6 7 1 1 1 1 1 1 1
顺序循环队列的实现
(6)清空队列。 void ClearQueue(SeqQueue *SCQ) { SCQ->front=SCQ->rear=0; }
5.2.5
顺序循环队列应用实例
为了加深对顺序循环队列的理解,下面通过一个例子 说明顺序循环队列的应用。 例5_2 要求顺序循环队列不损失一个空间全部能够得 到有效利用,请采用设置标志位tag的方法解决“假溢出” 问题,实现顺序循环队列算法。
5.4.1
双端队列的定义
双端队列是一种特殊的队列,它是在线性表的两端对 插入和删除操作限制的线性表。双端队列可以在队列的任何 一端进行插入和删除操作,而一般的队列要求在一端插入元 素,在另一端删除元素。
队列左端
插入 删除
队列右端 a2 „
插入
a1 end1
an
删除
end2
5.4.2
双端队列的应用
5.2.4
顺序循环队列的实现
(4)出队操作。 int DeleteQueue(SeqQueue *SCQ,DataType *e) { if(SCQ->front==SCQ->rear) return 0; else { *e=SCQ->queue[SCQ->front]; SCQ->front=(SCQ->front+1)%QueueSize; return 1; } }
第5章
队列
队列和栈一样,也是一种重要的线性结构。它们都是 操作受限制的线性表,其特殊性在于限制线性表的插入和删 除等操作的位置。队列在操作系统和事务管理等软件设计中 应用广泛,如键盘输入缓冲区问题就是利用队列的思想实现 的。本章的学习内容包括队列的定义、队列的顺序存储、链 式存储及应用 .
5.1
队列的定义
5.3.2
链式队列的实现
(6)清空队列。 void ClearQueue(LinkQueue *LQ) { while(LQ->front!=NULL) { LQ->rear=LQ->front->next; free(LQ->front); LQ->front=LQ->rear; } }
5.3.3
双端队列是一个可以任何一端进行插入和删除的线性 表,现在采用一个一维数组作为双端队列的数据存储结构, 试编写入队算法和出队算法。
0 队列左端 end1 end2 1 2 3 4 5 6 7 队列右端
5.4.2
双端队列的应用
例5_4 编写算法,利用顺序存储结构实现双端队列的 入队和出队操作。
5.5
5.2.4
顺序循环队列的实现
(5)取队头元素。 int GetHead (SeqQueue SCQ,DataType *e) { if(SCQ.front==SCQ.rear) return 0; else { *e=SCQ.queue[SCQ.front]; return 1; } }
5.2.4
5.3.2
链式队列的实现
(1)队列的初始化操作。 void InitQueue(LinkQueue *LQ) { LQ->front=LQ->rear =(LQNode*)malloc(sizeof(LQNode)); if(LQ->front==NULL) exit(-1); LQ ->front->next=NULL; }
5.2.4
顺序循环队列的实现
(2)判断队列是否为空。 int QueueEmpty(SeqQueue SCQ) { if(SCQ.front== SCQ.rear) return 1; else return 0; }
5.2.4
顺序循环队列的实现
(3)入队操作。 int EnterQueue(SeqQueue *SCQ,DataType e) { if(SCQ->front== (SCQ->rear+1)%QueueSize) return 0; SQ->queue[SCQ->rear]=e; SCQ->rear=(SCQ->rear+1)%QueueSize; return 1; }
5.2.3
顺序循环队列的表示
(2)少用一个存储空间。队空的判断条件front==rear ,front==(rear+1)%QueueSize表示队满。入队的操作: rear=(rear+1)%QueueSize,Q[rear]=x。出队的操作: front=(front+1)%QueueSize。
5.2.1
顺序队列的表示
(4)出队操作。 int DeleteQueue(SeqQueue *SQ,DataType *e) { if(SQ->front==SQ->rear) return 0; else { *e=SQ->queue[SQ->front]; SQ->front=SQ->front+1; return 1; } }
5.3.2
链式队列的实现
(2)判断队列是否为空。 int QueueEmpty(LinkQueue LQ) { if(LQ.rear->next==NULL) return 1; else return 0; }
5.3.2
链式队列的实现
(3)入队操作。 int EnterQueue(LinkQueue *LQ,DataType e) { LQNode *s; s=(LQNode*)malloc(sizeof(LQNode)); if(!s) exit(-1); s->data=e; s->next=NULL; LQ->rear->next=s; LQ->rear=s; return 1; }
Fra Baidu bibliotek
0 队列左端
1
2 c front=2
3 d
4 e
5 f
6 g
7 h
8 i
9 j
10 k
11 l 队列右端 rear=12
5.2.3
顺序循环队列的表示
1.顺序循环队列 2.顺序循环队列的队空和队满判断
front rear
8 7 6 5 4 3 2 9 0 1
i h
7 8 6
j
9 0 1
front rear
链式队列应用实例
下面通过一个实例来说明链式队列的具体使用。 例5_3 编程判断一个字符序列是否是回文。回文是指 一个字符序列以中间字符为基准两边字符完全相同,即顺着 看和倒着看是相同的字符序列。如字符序列“XYZAZYX”就 是回文,而字符序列"XYZBZXY"就不是回文。
5.4
双端队列
双端队列和栈、队列一样,也是一种操作受限的线性 表。本节的主要内容包括双端队列的定义和双端队列的应用 。
a b c
g f
5 4 3
2
e
(a)队空
d
(b)队满
5.2.3
顺序循环队列的表示
(1)增加一个标志位。设这个标志位为flag,初始化 为flag=0,当入队列成功flag=1,出队列成功flag=0,则队 空的判断条件:front==rear&&flag==0,队满的判断条件 :front==rear&&flag==1。
5.2.1
顺序队列的表示
(1)队列的初始化操作。 void InitQueue(SeqQueue *SQ) /*将顺序队列初始化为空队列只需要把队头指针和队尾 指针同时置为0*/ { SQ->front=SQ->rear=0; }
5.2.1
顺序队列的表示
(2)判断队列是否为空。 int QueueEmpty(SeqQueue SQ) /*判断队列是否为空,队列为空返回1,否则返回0*/ { if(SQ.front==SQ.rear) return 1; else return 0; }
5.2.1
顺序队列的表示
例5_1 编程实现顺序队列的入队操作和出队操作,并 将出队结果输出。
5.2.2
顺序队列的“假溢出”
按照以上顺序存储的方法,有可能会造成“假溢出”
。
0 队列左端 a front=0 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i rear=9 9 10 11 队列右端
队列也是一种限定性线性表,允许在表的一端进行插 入操作,在表的另一端进行删除操作。本节主要介绍队列的 定义和队列的抽象数据类型。
5.1.1
队列的定义
队列是一种特殊的线性表,它包含一个队头(front) 和一个队尾(rear)。其中,队头只允许删除元素,队尾只 允许插入元素。队列的特点是先进入队列的元素先出来,即 先进先出(FIFO)。
5.2.1
顺序队列的表示
(3)入队操作。 int EnterQueue(SeqQueue *SQ,DataType x) /*将元素x插入到顺序队列SQ中,插入成功返回1,否 则返回0*/ { if(SQ->rear==QueueSize) return 0; SQ->queue[SQ->rear]=x; SQ->rear=SQ->rear+1; return 1; }
rear front
i h
7 8 6 9 0 1 5 4 3 2
a b c
g f
e
d
5.2.4
顺序循环队列的实现
顺序循环队列的主要操作包括初始化操作、判断队列 是否为空、入队操作、出队操作、取队头元素和清空队列。
5.2.4
顺序循环队列的实现
(1)初始化操作。 void InitQueue(SeqQueue *SCQ) { SCQ ->front=SCQ ->rear=0; }
5.3
队列的链式表示及实现
采用链式存储的队列被称为链式队列或链队列。本节 的学习内容包括链式队列的表示、链式队列的实现和链式队 列的应用。链式队列具有不需要事先分配内存单元、不会产 生溢出、存储单元可以有效利用的优点,在进行插入操作时 不需要考虑队满的情况。
5.3.1
链式队列的表示
1.链式队列 2.链式循环队列
front
a b c
. . .
front
a b
. . .
rear
f
rear
f
5.3.1
链式队列的表示
front rear
front a rear
front
a
b
c rear
front
a
b
c rear
5.3.1
链式队列的表示
2.链式循环队列
a b
„
h
rear
rear
5.3.2
链式队列的实现
链式队列的实现包括初始化操作、判断队列是否为空 、入队、出队、取队列的队头元素、清空队列操作。
出队列
a1
front
a2
„
ai
„
an
rear
入队列
5.1.2
队列的抽象数据类型
1.数据对象集合 2.基本操作集合
5.2
队列的顺序表示及实现
队列有两种存储表示:顺序存储和链式存储。采用顺 序存储结构的队列被称之为顺序队列,采用链式存储结构的 队列被称之为链式队列。
5.2.1
顺序队列的表示
顺序队列通常采用一维数组进行存储。其中,连续的 存储单元依次存放队列中的元素。同时,使用两个指针分别 表示数组中存放的第一个元素和最后一个元素的位置。其中 ,指向第一个元素的指针被称为队头指针front,指向最后 一个元素的位置的指针被称为队尾指针rear。