1 / 18

(第六讲)

数据结构. (第六讲). 绍兴文理学院. 计算机系计算机应用教研室. 怎样让数据 排队 ?. 第 3 章 栈和队列( 2 ). 一、教学目的: 明确队列的有关概念;掌握队列的逻辑结构和存储结构,掌握队列的基本操作;掌握队列的初步应用。. 二、教学重点: 队列的有关概念;队列的逻辑结构和存储结构,队列的基本操作;队列的初步应用。. 三、教学难点: 循环队列的有关概念和操作;队列的初步应用。算法实现 能力的训练。 四、教学过程:. §3.4 队列 (Queue). a 1 a 2 a 3 a n. TKS. 4.

Download Presentation

(第六讲)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 数据结构 (第六讲) 绍兴文理学院 计算机系计算机应用教研室

  2. 怎样让数据排队?

  3. 第3章 栈和队列(2) 一、教学目的:明确队列的有关概念;掌握队列的逻辑结构和存储结构,掌握队列的基本操作;掌握队列的初步应用。 二、教学重点:队列的有关概念;队列的逻辑结构和存储结构,队列的基本操作;队列的初步应用。 三、教学难点:循环队列的有关概念和操作;队列的初步应用。算法实现能力的训练。 四、教学过程:

  4. §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

  5. 3、队列的两个重要操作 … … a2 an a1 … … a1 a2 an TKS 5 入队操作 EnQueue(&Q,e) 初始条件:队列Q已存在。 操作结果:将元素e插入到Q的队尾。 e 出队操作 DeQueue(&Q,&e) 初始条件:Q为非空队列。 操作结果:删除Q的队头元素,并用e返回其值。 11:33

  6. §3.4.2 循环队列(Circular Queue) ——队列的顺序表示和实现 TKS 6 1、概念:顺序存储的队列称为顺序队。 即用一组地址连续的存储单元依次存放从队列头到队列尾的元素。 因为队列的队头和队尾都是活动的,因此,除了队列的数据区外还有队头、队尾两个指针(标)。 2、结构定义 define MAXSIZE 100 // 队列的最大容量 struct sequeue { qelemtype *base; // 队列的存储空间(首地址) int front; // 队首指针(下标) int rear; // 队尾指针(下标) }; 11:33

  7. 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

  8. 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

  9. 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

  10. 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

  11. 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

  12. (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

  13. §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

  14. TKS 14 4、结构定义 typedef struct qnode // 结点类型 { QElemType data; QNode *next; } *QueuePtr; struct linkqueue // 链队列类型 { QueuePtr front; // 队头指针 QueuePtr rear; // 队尾指针 }; 11:33

  15. 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

  16. (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

  17. §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

  18. ③核心算法 五、作业: 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

More Related