180 likes | 312 Views
数据结构. (第六讲). 绍兴文理学院. 计算机系计算机应用教研室. 怎样让数据 排队 ?. 第 3 章 栈和队列( 2 ). 一、教学目的: 明确队列的有关概念;掌握队列的逻辑结构和存储结构,掌握队列的基本操作;掌握队列的初步应用。. 二、教学重点: 队列的有关概念;队列的逻辑结构和存储结构,队列的基本操作;队列的初步应用。. 三、教学难点: 循环队列的有关概念和操作;队列的初步应用。算法实现 能力的训练。 四、教学过程:. §3.4 队列 (Queue). a 1 a 2 a 3 a n. TKS. 4.
E N D
数据结构 (第六讲) 绍兴文理学院 计算机系计算机应用教研室
第3章 栈和队列(2) 一、教学目的:明确队列的有关概念;掌握队列的逻辑结构和存储结构,掌握队列的基本操作;掌握队列的初步应用。 二、教学重点:队列的有关概念;队列的逻辑结构和存储结构,队列的基本操作;队列的初步应用。 三、教学难点:循环队列的有关概念和操作;队列的初步应用。算法实现能力的训练。 四、教学过程:
§3.4 队列(Queue) a1 a2 a3 an TKS 4 §3.4.1 队列的类型定义 1、定义 队列是只允许在一端删除,在另一端插入元素的线性表。 允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear)。 出队列 入队列 front rear 2、特性 先进先出(FIFO, First In First Out) 第一个入队的元素在队头, 最后一个入队的元素在队尾, 第一个出队的元素为队头元素, 最后一个出队的元素为队尾元素。 11:33
3、队列的两个重要操作 … … a2 an a1 … … a1 a2 an TKS 5 入队操作 EnQueue(&Q,e) 初始条件:队列Q已存在。 操作结果:将元素e插入到Q的队尾。 e 出队操作 DeQueue(&Q,&e) 初始条件:Q为非空队列。 操作结果:删除Q的队头元素,并用e返回其值。 11:33
§3.4.2 循环队列(Circular Queue) ——队列的顺序表示和实现 TKS 6 1、概念:顺序存储的队列称为顺序队。 即用一组地址连续的存储单元依次存放从队列头到队列尾的元素。 因为队列的队头和队尾都是活动的,因此,除了队列的数据区外还有队头、队尾两个指针(标)。 2、结构定义 define MAXSIZE 100 // 队列的最大容量 struct sequeue { qelemtype *base; // 队列的存储空间(首地址) int front; // 队首指针(下标) int rear; // 队尾指针(下标) }; 11:33
3、约定和初始结构操作 TKS 7 约定:初始化创建空队列时,令front=rear=0,每当插入新的队尾元素时,“尾指针rear增1”;每当删除队头元素时,“头指针front增1”。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队尾元素的下一个位置。 初始结构操作: ◆定义一个指向队列的变量:sequeue q; ◆队列的数据区:q->base[0] ~ q->base[MAXSIZE-1] ◆队首指针(下标):q->front ◆队尾指针(下标):q->rear 11:33
J5 J4 4 rear rear rear J3 3 front front front J2 J2 2 J1 front 1 rear 0 ? 又有J6入队, 怎么办? TKS 8 4、队列中元素入队和出队及指针变化情况 (d)J3,J4和J5相继入队之后,J2出队 (b)J1,J2相 继入队列 (a)空队列 (c)J1出队 此时,队尾指针已经移到了最后,再有元素入队就会出现溢出,而事实上此时队中并未真的“满员”,这种现象为“假溢出”,这是由于“队尾入队头出”这种受限制。 11:33
5、构造循环队列 3 1 2 J6 front rear J5 J7 rear front J8 J4 J9 rear 5 5 4 0 4 0 3 1 3 1 2 2 ? 5 如何判断循环队列 队空、队满? 4 0 front J6 J5 rear J4 TKS 9 解决假溢出的方法之一是将队列的数据区base[0..MAXSIZE-1]看成头尾相接的循环结构,头尾指针的关系不变,队尾指针加1时从maxSize-1直接进到0将其称为“循环队列”。 J7 队空、队满 都有front=rear 队满 队空 11:33
6、循环队列中指针(下标)的移动方法 3 1 2 rear front 5 4 0 J6 J5 J4 TKS 10 ◆ 出队:队头指针进1: front=(front+1) % maxSize; ◆ 入队:队尾指针进1: rear=(rear+1) % maxSize; ◆ 队列初始化:front =rear=0; 7、队满与队空的判断 两种方法: Ⅰ 另设一个标志位以区分队空、队满。 Ⅱ 少用(损失)一个存储单元。一般用这种方法。这种方法下: 队空条件:front == rear; 队满条件:(rear + 1) % maxSize == front 11:33
8、结构定义 TKS 11 #define maxsize 100 struct sqqueue { qelemtype *base; int front; int rear; }; 9、循环队列的基本操作 (1) 初始化循环队列 void initqueue(squque &q) {q.base=new elemtype[maxsize]; if(!q.base) exit(0); q.front=q.rear=0; } (2) 求队列长度 int queuelength (sqqueue q) {return (q.rear-q.front+ maxsize)%maxqsize; } 11:33
(3) 入队 TKS 12 int enqueue(sqqueue &q,elemtype e) {if((q.rear+1)%maxsize==q->front) return error; q.base[q.rear]=e; q.rear=(q.rear+1)%maxqsize; return 1; } (4) 出队 int dequeue(sqqueue &q, elemtype &e) {if(q.front==q.rear) return error; e=q.base[q.front]; q.front=(q.front+1)%maxsize; return 1; } 11:33
§3.4.3 链队列 ——队列的链式存储表示和实现 ∧ ∧ … an an ∧ ∧ front front a3 a1 a1 a2 a2 a1 ∧ ∧ front rear rear front … rear TKS 13 1、概念链式存储的队称为链队。 2、链队示意图 3、队列运算指针变化状况 rear q q 空队 一个元素队 q 多个元素队 11:33
TKS 14 4、结构定义 typedef struct qnode // 结点类型 { QElemType data; QNode *next; } *QueuePtr; struct linkqueue // 链队列类型 { QueuePtr front; // 队头指针 QueuePtr rear; // 队尾指针 }; 11:33
5、基本操作 TKS 15 (1) 链队的初始化 int initqueue(linkqueue &q) // 构造一个空队列q { q,front=q.rear=new qnode; if(!q.front) exit(-1); // 存储分配失败 q.front->next=NULL; return 1; } (2) 入队 int enqueue(linkqueue &q,qelemtype e) { p=new qnode; if(!p) exit(-1); // 存储分配失败 p->data=e; p->next=NULL; q.rear->next=p; q.rear=p; return 1; } 11:33
(3) 出队 TKS 16 int dequeue(linkqueue &q,qelemtype &e) { if(q.front==q.rear) return 0; p=q.front->next; e=p->data; q.front->next=p->next; if(q.rear==p) q.rear=q.front; delete p; return 1; } 11:33
§3.5 队列的应用 TKS 17 例3.3 求二项式系数值(杨辉三角) 第 1 行 1 1 第 2 行 1 2 1 第 3 行 1 3 3 1 第 4 行 1 4 6 4 1 ① 分析: 设第 i-1行的值:(a[0]=0) a[1] … a[i] (a[i+1]=0) 则第 i 行的值:b[j] = a[j-1]+a[j], j=1,2,…,i+1 ②算法思想: 在构造好第一行(0,1,1,0)后,存储于循环队列;每次从队首先后出队一个元素s和得到一个元素e,其相加的值s+e入队,e值若不为0,则输出,若为0,则0入队,为下一行的开始作准备。直至需要输出的行数为止。 11:33
③核心算法 五、作业: TKS 18 do {dequeue(q,s); e=q.base[q.front]; enqueue(q,s+e); if(e!=0) printf ("%5d",e); else enqueue(q,0); }while(e!=0); 1、书面作业:P70 1中(3)、(8)、(11)~(14) 2、上机编程: (数据结构编程练习)中 8836、8841 ? ④ 算法演示S6_2 ⑤运行结果S6_1 11:33