第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.

Slides:



Advertisements
Similar presentations
1 門市服務丙級技術士 技能檢定介紹 門市服務丙級技術士報告注意事項 證照名稱:門市服務丙級技術士 發照單位:行政院勞工委員會 有效期限:終生有效 考照時間:每年一次,皆為第一梯次 1. 簡章與報名書表發售時間:每年 1 月 2. 報名時間:每年 1 月。 3. 學科考試時間:每年 3.
Advertisements

生源地助学贷款系统还款功能优化说明 评审三局 2015年5月.
二、信用工具和外汇.
为您扬帆,助您远航! 徽商银行特色新产品介绍. 为您扬帆,助您远航! 徽商银行特色新产品介绍.
第7章 樹與二元樹 (Trees and Binary Trees)
動畫與遊戲設計 Data structure and artificial intelligent
公务卡使用说明.
第一章 C语言概述 计算机公共教学部.
数据结构概论 第2章 线性表 董黎刚 浙江工商大学信电学院
第三章 鏈結串列 Linked List.
计算机硕士专业基础—C语言 赵海英
C语言实现俄罗斯方块 邓友明( ) 胡文峰( ) 李乐( ) 李博( )
数据结构——树和二叉树 1/96.
第六章 树和二叉树.
第二章 线性表 1 线性表的逻辑结构及其基本操作 2 线性表的顺序存储结构 3 线性表的链式存储结构 4 静态链表 5 应用实例.
資料結構與C++程式設計進階 資料結構概論 講師:林業峻 CSIE, NTU 6/ 7, 2010.
第三章 堆疊與佇列的基本應用 3-1 簡介堆疊(Stack) 3-2 迷宮問題研究 3-3 佇列(queue)的介紹
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Linked List Operations
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
第3章 栈和队列 3.1 栈 3.2 队列 3.3 应用.
單向鏈結串列 Singly Linked Lists.
程式設計 博碩文化出版發行.
佇列 (Queue).
4.4 佇列 特徵: c b a c b d c b 新增 d 刪除 入口 入口 入口 尾端(rear) 尾端(rear) 尾端(rear)
資料結構 第5章 佇列.
講師:郭育倫 第3章 基本資料結構 講師:郭育倫
第8章 圖形結構(Graphs) 8-1 圖形的基本觀念 8-2 圖形的表示法 8-3 圖形的走訪 8-4 擴張樹
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第12章 樹狀搜尋結構 (Search Trees)
第十五章 Linked List, Stack and Queue
Ch.3 栈和队列 黄刘生 中国科学技术大学计算机系 国家高性能计算中心(合肥)
程序设计期末复习 黎金宁
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
第3章 栈和队列(二) 1/.
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第三章 栈和队列 3.1 栈 3.2 栈的应用举例 3.3 栈与递归的实现 3.4 队列.
第三章 栈和队列.
数据结构 Data Structure 中南大学 主讲人:王国军,郑瑾 中南大学信息院计科系
第 六 章 鏈結串列(Link List) 課程名稱:資料結構 授課老師:________ 2019/1/2.
資料結構與C++程式設計進階 堆疊與佇列(Stack & Queue) 講師:林業峻 CSIE, NTU 6/ 21, 2010.
五、链 表 1、单链表 2、双向链表 3、链表应用.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
佇列(queue) Lai Ah Fur.
第三章 栈和队列.
資料結構 第4章 堆疊.
严蔚敏、吴伟民编著 清华大学出版社 学习网站:
第四章 堆疊與佇列 課前指引 資料結構學科中,堆疊(Stack)與佇列是兩種相當典型的抽象資料型態,也是一種有特定進出規則的線性串列應用,主要特性是限制了資料插入與刪除的位置和方法。本章中將會介紹堆疊與佇列的概念與特性,及在計算機領域的各種相關應用。
Chapter6 队列(Queues) The Abstract Data Type
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
自我參考結構 (self-reference – 1)
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
Linked Lists Prof. Michael Tsai 2013/3/12.
第7章 樹與二元樹(Trees and Binary Trees)
Chap2 Stack & Queue.
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
1. 志明打算就客戶服務開發一個語音互動(IVR)系統, 顧客可透過電話鍵盤與系統進行互動。
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Chapter 2 Entity-Relationship Model
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
資料結構與C++程式設計進階 C++與資料結構 講師:林業峻 CSIE, NTU 7/ 5, 2010.
Presentation transcript:

第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列

6-1 佇列的基礎-說明 「佇列」(Queues)是一種和堆疊十分相似的資料結構,在日常生活中隨處可見的排隊人潮,例如:在郵局排隊寄信、銀行排隊存錢或電影院前排隊買票的隊伍,其組成的線性串列就是一種佇列,如下圖所示:

6-1 佇列的基礎-操作 排隊的隊伍是在尾端(Rear)加入隊伍,如同佇列在尾端存入資料,當前端(Front)寄完信、存完錢或買完票後,人就離開隊伍,如同佇列從前端取出資料,所以佇列的基本操作,如下所示: dequeue():從佇列取出資料,每執行一次,就從前端取出一個資料。 enqueue():在尾端將資料存入佇列。 isQueueEmpty():檢查佇列是否是空的,以便判斷是否還有資料可以取出。

6-1 佇列的基礎-特性 佇列的資料因為是從尾端一一存入,佇列的內容是依序執行enqueue(1)、enqueue(2)、enqueue(3)、enqueue(4)和enqueue(5)的結果,接著從佇列依序執行dequeue()取出佇列資料,如下所示: dequeue():1 dequeue():2 dequeue():3 dequeue():4 dequeue():5 上述取出的順序是1、2、3、4、5,和存入時完全相同,稱為「先進先出」(First In, First Out)特性。總之,佇列擁有的特性,如下: 從佇列的尾端存入資料,從前端讀取資料。 資料存取的順序是先進先出(First In, First Out),也就是先存入佇列的資料,先行取出。

6-1 佇列的基礎-應用 以計算機科學來說,佇列的主要用途是作為資料緩衝區,例如:因為電腦周邊設備的處理速度遠不如CPU,所以印表機列印報表時,需要使用佇列作為資料暫存的緩衝區,如下圖所示:

6-2 佇列的表示法 6-2-1 使用陣列建立佇列 6-2-2 使用鏈結串列建立佇列

6-2-1 使用陣列建立佇列-標頭檔 01: /* 程式範例: Ch6-2-1.h */ 02: #define MAXQUEUE 10 /* 佇列的最大容量 */ 03: int queue[MAXQUEUE]; /* 佇列的陣列宣告 */ 04: int front = -1; /* 佇列的前端 */ 05: int rear = -1; /* 佇列的尾端 */ 06: /* 抽象資料型態的操作函數宣告 */ 07: extern int isQueueEmpty(); 08: extern int enqueue(int d); 09: extern int dequeue();

6-2-1 使用陣列建立佇列 佇列是分別從兩端存入和取出資料。 以陣列建立佇列,指標front(前端)及rear(後端)變數是用來儲存陣列的索引值。 front(前端) 變數的索引值是指向目前佇列中第1個元素的前一個索引值。rear(後端)變數是指向剛存入元素的索引值(最後ㄧ個)

6-2-1 使用陣列建立佇列-存入元素(步驟) 函數enqueue()是將資料存入佇列的rear尾端,其步驟如下所示: Step 1: 檢查佇列是否已滿,如果沒有: Step 2:將尾端指標rear往前移動,也就是將指標rear加1。 Step 3:將值存入尾端指標rear所指的陣列元素。 queue[++rear] = d;

6-2-1 使用陣列建立佇列-存入元素(圖例)

6-2-1 使用陣列建立佇列-取出元素(步驟) 函數dequeue()是從佇列的front前端取出資料,其步驟如下所示: Step 1:檢查佇列是否已空,如果沒有: Step 2:將前端指標front往前移,即把其值加1。 Step 3:取出前端指標front所指的陣列元素。 return queue[++front];

6-2-1 使用陣列建立佇列-取出元素(圖例)

6-2-1 使用陣列建立佇列-佇列是否已空 在取出資料5後,指標front是指向佇列指標rear的前1個陣列索引值4,目前尚有1個元素,請注意!front指標是指向目前佇列中第1個元素的前一個元素。 換句話說,只需比較兩個front和rear指標是否相等,就可以知道佇列是否已空。 如果front指標是指向佇列中的第1個元素,當取出資料5後,front指標就已經和指標rear相同,都是索引值5,如此就無法判斷佇列到底是空了或還剩下1個元素。

6-2-1 使用陣列建立佇列-問題 陣列實作的佇列有一個大問題,因為front和rear變數的指標都是往同一個方向遞增,如果rear指標到達一維陣列的邊界MAXQUEUE-1,需要位移佇列元素才有空間存入其它佇列元素,就算佇列的一維陣列尚有一些空間,如下圖所示:

6-2-2 使用鏈結串列建立佇列-標頭檔 01: /* 程式範例: Ch6-2-2.h */ 02: struct Node { /* 佇列結構的宣告 */ 03: int data; /* 資料 */ 04: struct Node *next; /* 結構指標 */ 05: }; 06: typedef struct Node QNode; /* 佇列節點的新型態 */ 07: typedef QNode *LQueue; /* 串列佇列的新型態 */ 08: LQueue front = NULL; /* 佇列的前端 */ 09: LQueue rear = NULL; /* 佇列的尾端 */ 10: /* 抽象資料型態的操作函數宣告 */ 11: extern int isQueueEmpty(); 12: extern void enqueue(int d); 13: extern int dequeue();

6-2-2 使用鏈結串列建立佇列-存入元素(步驟) 函數enqueue()將資料存入佇列,插入成為串列的最後1個節點,其步驟如下所示: Step 1:建立一個新節點存入佇列資料。 new_node = (LQueue)malloc(sizeof(QNode)); new_node->data = d; new_node->next = NULL; Step 2:檢查rear指標是否是NULL,如果是,表示第一次存入資料,則: (1) 如果是,將開頭指標front指向新節點。 front = new_node; (2) 如果不是,將rear指標所指節點的next指標指向新節點。 rear->next = new_node; Step 3:將後rear指標指向新節點。 rear = new_node;

6-2-2 使用鏈結串列建立佇列-存入元素(圖例) 例如:依序存入值1~3到佇列,可以看到rear指標一直都是指向串列的最後1個節點,如下圖所示:

6-2-2 使用鏈結串列建立佇列-取出元素(步驟) 函數dequeue()是從佇列取出資料,也就是刪除串列第1個節點,其步驟如下所示: Step 1:若front等於rear指標,表示只剩一個節點,將rear設為NULL。 if ( front == rear ) rear = NULL; Step 2:將佇列的前端指標front指向下一個節點。 ptr = front; front = front->next; Step 3:取出第1個節點內容。 temp = ptr->data; Step 4:釋回第1個節點的節點記憶體。 free(ptr);

6-2-2 使用鏈結串列建立佇列-取出元素(圖例) 例如:在依序存入值1~3到佇列後,呼叫二次dequeue()函數取出佇列值,如下圖所示:

6-3 環狀佇列-說明 「環狀佇列」(Circular Queue)也是使用一維陣列實作的有限元素數佇列,其差異只在使用特殊技巧來處理陣列索引值,將陣列視為一個環狀結構,佇列的索引指標周而復始的在陣列中環狀的移動,如下圖所示:

6-3 環狀佇列-標頭檔 01: /* 程式範例: Ch6-3.h */ 02: #define MAXQUEUE 4 /* 佇列的最大容量 */ 03: int queue[MAXQUEUE]; /* 佇列的陣列宣告 */ 04: int front = -1; /* 佇列的前端 */ 05: int rear = -1; /* 佇列的尾端 */ 06: /* 抽象資料型態的操作函數宣告 */ 07: extern int isQueueEmpty(); 08: extern int isQueueFull(); 09: extern int enqueue(int d); 10: extern int dequeue();

6-3 環狀佇列-存入元素1 函數enqueue()是在rear尾端將資料存入佇列,因為是環狀結構的陣列,所以當rear到達陣列邊界時,需要特別處理,如下圖所示:

6-3 環狀佇列-存入元素2 MAXQUEUE為4的環狀佇列,當rear = 3時到達陣列邊界,此時再新增佇列元素5,rear++等於4,超過陣列尺寸,所以需要將它歸0,如下所示: rear++; if ( rear == MAXQUEUE ) rear = 0; ?:條件運算子,如下所示: rear = ( rear+1 == MAXQUEUE ) ? 0 : rear+1; 使用餘數運算,如下所示: rear = (rear+1) % MAXQUEUE;

6-3 環狀佇列-取出元素1 函數dequeue()是在front前端從佇列取出資料,因為是環狀結構的陣列,所以當front到達陣列邊界時,需要特別處理,如下圖所示:

6-3 環狀佇列-取出元素2 MAXQUEUE為4的環狀佇列,當front = 3時到達陣列邊界,此時再從佇列取出元素3,front++等於4,超過陣列尺寸,所以需要將它歸0,如下所示: front++; if ( front == MAXQUEUE ) front = 0; ?:條件運算子,如下所示: front = ( front+1 == MAXQUEUE ) ? 0 : front+1; 使用餘數運算,如下所示: front = (front+1) % MAXQUEUE;

6-3 環狀佇列-佇列是否是空的1 函數isQueueEmpty()可以判斷環狀佇列是否已經空了。現在環狀佇列尚餘1個元素,如下圖所示:

6-3 環狀佇列-佇列是否是空的2 再執行一次dequeue()取出最後1個元素4,可以發現front和rear指標相等,換句話說,只需判斷兩個指標是否相等,就可以判斷環狀佇列是否已經空了,如下所示: if ( front == rear ) return 1; else return 0;

6-3 環狀佇列-佇列是否己滿1 函數isQueueFull()可以判斷環狀佇列是否已滿。現在環狀佇列尚有1個空間沒有存入元素,如下圖所示:

6-3 環狀佇列-佇列是否己滿2 再執行enqueue(6)新增元素6,可以發現front和rear指標相等,沒有辦法判斷環狀佇列是已空和全滿,因為兩個指標都是指向相同索引值1。 所以,環狀佇列全滿就是指標rear和front相隔一個空間,換句話說,為了分辨環狀佇列是已空和全滿,其實際的儲存空間是陣列尺寸減1,如下所示: int pos; pos = (rear+1) % MAXQUEUE; if ( front == pos ) return 1; else return 0;

6-4 雙佇列 6-4-1 輸入限制性雙佇列 6-4-2 輸出限制性雙佇列

6-4 雙佇列-說明 「雙佇列」(Deques)是英文名稱(Double-ends Queues)的縮寫,雙佇列的二端如同佇列的前尾端,都允許存入或取出資料,如下圖所示:

6-4 雙佇列-種類 雙佇列依其應用分為多種存取方式。常見的雙佇列,如下所示: 輸入限制性雙佇列(Input Restricted Deque)。 輸出限制性雙佇列(Output Restricted Deque)。 上述雙佇列是使用在電腦CPU的排程,排程在多人使用的電腦是重要觀念,因為同時有多人使用同一個CPU,而CPU在每一段時間內只能執行一個工作,所以將每個人的工作集中擺在一個等待佇列,等待CPU執行完一個工作後,再從佇列取出下一個工作來執行,排定工作誰先誰後的處理稱為「工作排程」(Jobs Scheduling)。

6-4-1 輸入限制性雙佇列-說明 輸入限制性雙佇列(Input Restricted Deque)是限制存入只能在其中一端,取出可以在兩端的任何一端,雙佇列只有一端存入,兩端都可以輸出,所以佇列輸出的結果擁有多種組合。

6-4-1 輸入限制性雙佇列-標頭檔 01: /* 程式範例: Ch6-4-1.h */ 02: #define MAXQUEUE 10 /* 佇列的最大容量 */ 03: int deque[MAXQUEUE]; /* 佇列的陣列宣告 */ 04: int front = -1; /* 佇列的前端 */ 05: int rear = -1; /* 佇列的尾端 */ 06: /* 抽象資料型態的操作函數宣告 */ 07: extern int isDequeEmpty(); 08: extern int isDequeFull(); 09: extern int endeque(int d); 10: extern int dedeque_rear(); 11: extern int dedeque_front();

6-4-2 輸出限制性雙佇列-說明 輸出限制性雙佇列(Output Restricted Deque)是限制取出只能在一端,卻可以從兩端的任何一端存入元素,如下圖所示:

6-4-2 輸出限制性雙佇列-標頭檔 01: /* 程式範例: Ch6-4-2.h */ 02: struct Node { /* 佇列結構的宣告 */ 03: int data; /* 資料 */ 04: struct Node *next; /* 結構指標 */ 05: }; 06: typedef struct Node QNode;/* 雙佇列節點的新型態 */ 07: typedef QNode *LDeque; /* 串列雙佇列的新型態 */ 08: LDeque front = NULL; /* 雙佇列的前端 */ 09: LDeque rear = NULL; /* 雙佇列的尾端 */ 10: /* 抽象資料型態的操作函數宣告 */ 11: extern int isDequeEmpty(); 12: extern void endeque_rear(int d); 13: extern void endeque_front(int d); 14: extern int dedeque();

本章結束

複習(一) 1.舉例說明何謂「佇列」(Queues)? 2.佇列的特性為何? 3.舉例說明電腦如何使用「佇列」? 4. 資料結構裡First In , First Out 意義為何? 5.為何佇列的front指標不指向佇列中的第1個元素? 6. enqueue()是將資料存入佇列的rear尾端,其步驟為何? 7. dequeue()是從佇列的front前端取出資料,其步驟為何? 8. 何謂「環狀佇列」(Circular Queue)? 9.如何判斷環狀佇列是否已空? 10.為何環狀佇列實際的儲存空間是陣列尺寸減1?

複習(二) 11. 鏈結串列建立之佇列enqueue() 步驟為何? 12.鏈結串列建立之佇列dequeue() 步驟為何? 13.何為「雙佇列」(Deques)? 14.電腦如何使用資料結構做「工作排程」? 15.何謂輸入限制性雙佇列(Input Restricted Deque)? 16. 何謂輸出限制性雙佇列(Output Restricted