第三章 栈和队列 第二部分 队列(Queue) 2019/4/8.

Slides:



Advertisements
Similar presentations
國立中興大學 法律學系     系所介紹          .
Advertisements

國立中興大學 法律學系     系所介紹          .
迷 宫 最短路径 施沈翔.
问题的提出: 例1 把十进制整数转换为二至十六之间的任一进制数输出。
第五讲 队列.
数据结构——树和二叉树 1/96.
第六章 树和二叉树.
資料結構與C++程式設計進階 資料結構概論 講師:林業峻 CSIE, NTU 6/ 7, 2010.
Linked List Operations
第3章 栈和队列 3.1 栈 3.2 队列 3.3 应用.
單向鏈結串列 Singly Linked Lists.
第3章 栈和队列.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
主要内容: 1.第一部分 概述 2.第二部分 线性表、栈、队列
第二章 线性表 线性表 顺序表 链表 顺序表与链表的比较.
第三章栈和队列 栈 队列 递归.
佇列 (Queue).
資料結構 第5章 佇列.
数据结构.
Ch.3 栈和队列 黄刘生 中国科学技术大学计算机系 国家高性能计算中心(合肥)
线性表小结 元素之间的线性关系 顺序表 顺序表:元素相邻存储 单链表:后继指针链接 一维数组 给定下标随机存取
本 章 说 明 3.1 栈 3.2 栈的应用举例 3.3 栈与递归的实现 3.4 队 列 本 章 小 结 返回主目录.
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
第3章 栈和队列(二) 1/.
第三章 栈和队列 栈和队列是两种重要的数据结构。
第3章 栈和队列 丽水学院工学院.
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第2章 线性表 2.1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式表示和实现 2.4 一元多项式的表示.
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
Chapter 6 队列(QUEUES).
第 3 讲 线性表(一).
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第三章 栈和队列 3.1 栈 3.2 栈的应用举例 3.3 栈与递归的实现 3.4 队列.
第3章 栈和队列(一).
第三章 栈和队列.
数据结构 Data Structure 中南大学 主讲人:王国军,郑瑾 中南大学信息院计科系
資料結構與C++程式設計進階 堆疊與佇列(Stack & Queue) 講師:林業峻 CSIE, NTU 6/ 21, 2010.
第一章 绪论.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
内容回顾 线性表的定义和特点 线性表的顺序存储及查找、插入和删除.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
第3章 栈和队列 3.1 栈 本章主题:栈和队列的应用 教学目的:掌握栈和队列的应用方法,理解栈的重要作用
数 据 结 构 刘家芬 Sept 2012.
佇列(queue) Lai Ah Fur.
第三章 栈和队列.
严蔚敏、吴伟民编著 清华大学出版社 学习网站:
第四章 堆疊與佇列 課前指引 資料結構學科中,堆疊(Stack)與佇列是兩種相當典型的抽象資料型態,也是一種有特定進出規則的線性串列應用,主要特性是限制了資料插入與刪除的位置和方法。本章中將會介紹堆疊與佇列的概念與特性,及在計算機領域的各種相關應用。
顺序表的插入.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
王玲 第 2 章 线性表 王玲 2019/2/25.
第四章 栈和队列 4.1栈 4.2栈的应用 4.3队列 4.3队列应用.
计算机软件技术基础 数据结构与算法(3).
顺序表的删除.
Linked Lists Prof. Michael Tsai 2013/3/12.
队列及其实现.
Chap2 Stack & Queue.
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
第 四 讲 线性表(二).
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
第 六 讲 栈和队列(一).
实验目的:掌握数据的顺序存储结构及它们在计算机中的操作。 实验内容:
第七讲 栈和队列(二) 1/.
算法3.3 void InitList_sq(SqList &L,int msize=LIST_INIT_SIZE)
第3章 栈和队列 3.1 栈 3.2 队列.
Chapter 2 Entity-Relationship Model
第三章 栈和队列.
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
第二章 线性表 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
Presentation transcript:

第三章 栈和队列 第二部分 队列(Queue) 2019/4/8

3.2 队列 逻辑结构:先进先出(FIFO) 只能在一端插入、另一端删除的线性表 队尾(rear):允许插入的一端 队头(front):允许删除的一端 a1 a2 a3…………………….an 入队 出队 front rear 队列Q=(a1, a2, ……, an) 2019/4/8

队列实现 链队列:单链表 结点定义 typedef struct QNode { QElemType data; 队首指针 front:指向头结点 队尾指针 rear:指向队尾元素 头结点 ^ …... front 队头 队尾 rear 结点定义 typedef struct QNode { QElemType data; struct QNode *next ; } QNode , *QueuePtr ; 队列定义 typedef struct { QueuePtr front , rear ; } *LinkQueue ; 2019/4/8

空队 ^ q.front q.rear x x入队 ^ q.front q.rear y入队 x y q.front q.rear ^ 2019/4/8

******队列基本操作算法****** 单链队列的基本操作--------建立空队列 Status InitQueue(LinkQueue &Q){ //构造一个空队列Q Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q.front) exit(OVERFLOW); //存储分配失败 return OK; } Q.front->next=NULL; 2019/4/8

单链队列的基本操作--------销毁队列 Status DestroyQueue(LinkQueue &Q){ //销毁队列Q while(Q.front){ Q.rear=Q.front->next; free(Q.front); Q.front=Q.rear; } return OK; 2019/4/8

Status EnQueue ( LinkQueue Q , QElemType e) { QueuePtr p ; 入队算法 Status EnQueue ( LinkQueue Q , QElemType e) { QueuePtr p ; p=(QueuePtr) malloc ( sizeof ( QNode ) ); p->data = e ; p->next = NULL ; Q->rear->next = p; Q->rear = p ; return OK ; } 2019/4/8

Status DeQueue (LinkQueue Q , QElemType &e) { QueuePtr p ; 出队算法 Status DeQueue (LinkQueue Q , QElemType &e) { QueuePtr p ; if( Q->front = = Q->rear ) return ERROR ;//队空判断 p = Q->front->next ; //取出队头元素值 e = p->data; Q->front->next = p->next ; if ( p->next = = NULL) Q->rear = Q->front ; free(p); return OK ; } 当队列尾元素被删除后,队尾指针也丢失 因此需要给队尾指针重新赋值:指向头结点 2019/4/8

队列的顺序存储结构 一维数组:base [MAXQSIZE] 5 4 3 2 1 front = 0 rear = 0 队空 约定: 队空 (动态分配数组空间): typedef struct { QElemType *base ; //数组 int front , rear ; //队首,队尾(元素下标) int queuesize; //最大元素个数 } SqQueue , *SeqQueue ; 约定: rear:队尾元素后一位置 front:队头元素 初值 front = rear = 0 2019/4/8

队列的顺序存储结构 一维数组:base [MAXQSIZE] 5 5 4 4 rear 3 3 rear J3 2 2 rear J2 1 front = 0 rear = 0 1 2 3 4 5 队空 J1,J2,J3入队 1 2 3 4 5 front rear rear J3 rear J2 rear J1 入队列:base [ rear++] = e ; 2019/4/8

出队列:e= base[front++]; 队列的顺序存储结构 一维数组:base [MAXQSIZE] 1 2 3 4 5 J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear rear front J3 front J2 front J1 front J1,J2,J3出队 出队列:e= base[front++]; 2019/4/8

存在问题 设数组尺寸 M (=6) 当front = 0 , rear = M 时,再有元素入队发生溢出——真溢出 rear 1 2 3 4 5 J1,J2,J3,J4,J5,J6入队 J4 J5 J6 front J1 J2 J3 J7入队? 如何解决? 扩充空间 2019/4/8

存在问题 设数组尺寸为 M,则: 当front  0 , rear = M 时,再有元素入队发生溢出——假溢出 rear 1 2 3 4 5 J1,J2,J3出队 J4 J5 J6 front J7入队? 如何解决? 扩充空间? front 以前的空闲空间被浪费! 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 J1出队? 5 4 rear 3 J3 2 J2 1 front J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear J1出队? 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear 3 3 J3 J3 2 2 J2 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear J3 J2 front front++? J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear 3 3 J3 J3 2 2 J2 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear J3 J2 元素下移 front front 不动! J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear 3 3 J3 J3 2 2 J2 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear J3 front J2 front 不动! J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear 3 3 J3 J3 2 2 J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear J3 元素下移 front J2 front 不动! J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear rear -- 3 3 J3 2 J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear rear -- J3 front J2 front 不动! J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 5 5 4 4 rear rear -- 3 3 rear J3 2 J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear -- rear J3 front J2 front 不动! J1出队 2019/4/8

“假溢出”的解决方案 I 移动元素 队首固定,每次出队剩余元素向下移动 元素移动费时! 能否不移动元素? 5 5 4 4 rear 3 3 J1,J2,J3入队 1 2 3 4 5 front J1 J2 J3 rear 1 2 3 4 5 rear J3 front J2 J1出队 元素移动费时! 能否不移动元素? 2019/4/8

“假溢出”的解决方案 II 新元素如何利用队头前的空闲数组空间? base [ rear] = ‘J6’; rear 1 2 3 4 5 J4 J5 front J6入队 J6 base [ rear] = ‘J6’; 2019/4/8

“假溢出”的解决方案 II 新元素如何利用队头前的空闲数组空间? base [ rear] = ‘J6’; rear ++; 1 2 3 4 5 J6 base [ rear] = ‘J6’; J5 rear ++; (rear = 6) front J4 下标将越界!(队尾将超出数组) 令其返回数组前面空闲单元 0 (rear = 0;) 2019/4/8

“假溢出”的解决方案 II 新元素如何利用队头前的空闲数组空间? 若队尾将超出数组,令其返回数组前面空闲部分 若 rear + 1 = M,令 rear =0 1 2 3 4 5 J6 J5 front J4 rear J7入队? J1,J2,J3出队 2019/4/8

“假溢出”的解决方案 II 新元素如何利用队头前的空闲数组空间? 若队尾将超出数组,令其返回数组前面空闲部分 若 rear + 1 = M,令 rear =0 1 2 3 4 5 J6 J5 front J4 rear J7 J1,J2,J3出队 2019/4/8

“假溢出”的解决方案 II 新元素如何利用队头前的空闲数组空间? 若队尾将超出数组,令其返回数组前面空闲部分 在 J6 入队时: 若 rear + 1 = M,令 rear =0 1 2 3 4 5 J6 在 J6 入队时: if ( rear ++ > M ) rear = 0; else rear ++ ; J5 front J4 rear J7 J1,J2,J3出队 2019/4/8

“假溢出”的解决方案 II 循环队列 设想队列成环形,让base[0]接在base[M-1]之后 入队: if ( rear ++ > M ) rear = 0; else rear ++ ; M-1 1 front rear …... 求模(求余)运算 入队: base[rear]=e; rear=(rear+1)%M; 出队: e=base[front]; front=(front+1)%M; 队满、队空判定条件? 2019/4/8

队空:front==rear 队满:front==rear 1 2 3 4 5 rear front J4 J5 J6 1 2 3 4 5 front J4,J5,J6出队 J4 J5 J6 1 2 3 4 5 rear front J9 J8 J7 J7,J8,J9入队 rear 一般情况 如何区分队空、队满? 2019/4/8

J5 front J4,J5,J6出队 front J6 J4 rear front rear J7,J8,J9入队 J5 J6 J4 1 2 3 4 5 rear front J4 J5 J6 1 2 3 4 5 J4,J5,J6出队 front J4 J5 J6 1 2 3 4 5 rear front J9 J8 J7 J7,J8,J9入队 rear 一般情况 解决方案: 1、另外设一个标志以区别队空、队满 2019/4/8

J5 front J4,J5,J6出队 front J6 J4 rear front J7,J8,J9入队 J5 J6 J4 rear 1 2 3 4 5 rear front J4 J5 J6 1 2 3 4 5 J4,J5,J6出队 front front J7,J8,J9入队 J5 J6 J4 5 rear 一般情况 4 3 1 解决方案: 1、另外设一个标志以区别队空、队满 2、少用一个元素空间: 队空:front == rear 队满:(rear+1) % M == front 2 J7 J8 rear J9 入队时,已满! 2019/4/8

优先队列 (Priority Queue) 优先队列:每次从队列中取出的是具有最高优先权的元素 例:任务的优先权及执行顺序的关系 数字越小,优先权越高 2019/4/8

小 结 队列的插入运算在表的一端进行,而删除运算却在表的另一端进行。 小 结 队列的插入运算在表的一端进行,而删除运算却在表的另一端进行。 根据队列的这一特点,在使用顺序存储结构时,用了环形队列,这样可解决假溢出问题,但要特别注意队列满和队列空的条件及描述。 2019/4/8