Chapter14 Divide and Conquer

Slides:



Advertisements
Similar presentations
第二节 换元积分法 一、第一类换元积分 法(凑微分法) 二、第二类换元积分法. 问题 解决方法 利用复合函数,设置中间变量. 过程令 一、第一类换元积分法(凑微分法)
Advertisements

提升教學品質研討會 工學院教師教學經驗分享 長庚大學 資訊工程學系 / 醫療機電工程研究所 助理教授 趙一平 2015/04/10.
练一练: 在数轴上画出表示下列各数的点, 并指出这些点相互间的关系: -6 , 6 , -3 , 3 , -1.5, 1.5.
回顾上节课的内容 二分 有序 堆 平方级排序算法简单介绍 交换排序 冒泡排序 插入排序 选择排序.
举国上下抗击风雪灾害专刊 温暖行动 灾情告急年关近 万众一心齐抗灾 可歌可泣留千古 温暖行动遍人间 导读提示 阳关雨露出版社
作文选刊 作文之窗
小班早期阅读讲座.
圆的一般方程 (x-a)2 +(y-b)2=r2 x2+y2+Dx+Ey+F=0 Ax2+Bxy+Cy2+Dx+Ey+ F=0.
快乐假期 2010年第6期 总第54期 贝尔芬 主编 暑期作文专刊 《快乐假期》杂志社 出版.
在文章中插入图片 What to do? 任务一(1):请你在“愤怒的小鸟”这个文档中插入“红色小鸟”的图片。 要求:1、自学课本45-47页“做一做”的内容,找到在文档中插入图片的方法后,就动手试一试吧。 哪一小组最先完成,会加平时成绩10分噢,加油吧!
依“标”据“本”,命制考题 发表于《数学教学》2006年第9期 (华东师大核心“CN”刊物)
人教新课标版三年级数学下册 笔算除法.
第九章 排序 插入排序 交换排序 选择排序 归并排序 基数排序.
第八讲 排序算法 —— C++ 实现.
定积分的换元法 和分部积分法 换元公式 分部积分公式 小结 1/24.
第5章 定积分及其应用 基本要求 5.1 定积分的概念与性质 5.2 微积分基本公式 5.3 定积分的换元积分法与分部积分法
初中数学八年级下册 (苏科版) 10.4 探索三角形 相似的条件(2).
Hadoop I/O By ShiChaojie.
排序 Sorting.
快速排序法 (Quick Sort).
第十章 排序 10.1排序的基本概念 10.2简单排序方法(复杂度 O(n2))
第十章 内部排序.
强连通分量 无向图 1、任意两顶点连通称该图为连通图 2、否则将其中的极大连通子图称为连通分量 A D C B E 有向图
第八章 菜单设计 §8.1 Visual FoxPro 系统菜单 §8.2 为自己的程序添加菜单 §8.3 创建快捷菜单.
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
元素替换法 ——行列式按行(列)展开(推论)
Cyclic Hanoi问题 李凯旭.
第4章 非线性规划 一维搜索方法 2011年11月.
递归与分治策略.
What have we learned?.
数据结构 Data Structure CSU 主讲人:王国军,郑瑾 中南大学信息院计科系
Chapter 2 Program performance.
第九章 排序 概述 插入排序 交换排序 选择排序 归并排序 *基数排序 *外排序.
使用矩阵表示 最小生成树算法.
第十章内部排序 概述 插入排序 快速排序 选择排序 归并排序 基数排序.
专题作业.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
顺序表的删除.
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
第九章 排序 概述 插入排序 快速排序 交换排序(起泡排序) 选择排序 归并排序.
第二章 Java基本语法 讲师:复凡.
用计算器开方.
信号量(Semaphore).
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
iSIGHT 基本培训 使用 Excel的栅栏问题
§6.7 子空间的直和 一、直和的定义 二、直和的判定 三、多个子空间的直和.
1.2 子集、补集、全集习题课.
第4课时 绝对值.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
第九章 排序 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
上杭二中 曾庆华 上杭二中 曾庆华 上杭二中 曾庆华.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
分数再认识三 真假带分数的练习课.
正弦、余弦函数的性质 华容一中 伍立华 2017年2月24日.
生 物 信 息 学 Bioinformatics 巩晶 癌症研究中心 山东大学 医学院
第10章 排序 排序的基本概念 插入排序 选择排序 交换排序归并排序 基数排序 性能比较 主要知识点.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
找 因 数.
主讲人: 吕敏 { } Spring 2012 ,USTC 算法基础 主讲人: 吕敏 { } Spring 2012 ,USTC.
資料結構 老師:李崇明 助教:楊斯竣.
3.4 角的比较.
插入排序的正确性证明 以及各种改进方法.
算法的基本思想: 第6章 内部排序 6.2 气泡排序 将待排序的记录看作是竖着排列的“气泡”,关键字较小 的记录比较轻,从而要往上浮。
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
§4.5 最大公因式的矩阵求法( Ⅱ ).
第二次课后作业答案 函数式编程和逻辑式编程
8、9的认识 一年级组 李 晶.
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
Cfc Zeilberger 算法 陈焕林 陈永川 付梅 臧经涛 2009年7月29日.
9.3多项式乘多项式.
Presentation transcript:

Chapter14 Divide and Conquer 分而治之方法与软件设计的模块化方法非常相似。为了解决一个大的问题,可以: 1) 把它分成两个或多个更小的问题; 2) 分别解决每个小问题; 3) 把各小问题的解答组合起来,即可得到原问题的解答。 小问题通常与原问题相似,可以递归地使用分而治之策略来解决。 2/22/2019

一个用分治法编写的过程通常包括以下几部分:基值处理部分,(即把问题分到足够小后要进行的处理),分解问题的部分,递归调用部分和合并处理部分。 由于分治策略是把问题分成较小的与原问题类型相同的子问题,对子问题的处理过程与对原问题的处理过程是相同的。所以,分治法处理问题的算法可以自然地写成一个递归的过程。 2/22/2019

找出伪币问题 一个装有16个硬币的袋子。16个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。任务是找出这个伪造的硬币。 为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。 2/22/2019

金块问题 有一个老板有一袋金块。每个月将有两名雇员会因其优异的表现分别被奖励一个金块。按规矩,排名第一的雇员将得到袋中最重的金块,排名第二的雇员将得到袋中最轻的金块。 2/22/2019

金块问题 2/22/2019

金块问题 用函数M a x(程序1 - 3 1)通过n-1次比较找到最重的金块。找到最重的金块后,可以从余下的n-1个金块中用类似的方法通过n-2次比较找出最轻的金块。这样,比较的总次数为2n-3。 设c(n)为使用分而治之方法所需要的比较次数。为了简便,假设n是2的幂。当n=2时,c(n) = 1。对于较大的n,c(n) = 2c(n/2) + 2。当n是2的幂时,使用迭代方法可知c(n) = 3n/2 - 2。 在本例中,使用分而治之方法比逐个比较的方法少用了25%的比较次数。 2/22/2019

归并排序 可以运用分而治之方法来解决排序问题,问题是将n 个元素排成非递减顺序。 2/22/2019

归并排序-1 假设仅将n个元素的集合分成两个子集合。现在需要确定如何进行子集合的划分。 一种可能性就是把前面n-1个元素放到第一个子集中(称为A),最后一个元素放到第二个子集里(称为B)。按照这种方式对A递归地进行排序。由于B仅含一个元素,所以它已经排序完毕,在A排完序后,只需要将A和B合并起来。 2/22/2019

归并排序-1 把这种排序算法与InsertionSort(见程序2-15)进行比较,可以发现这种排序算法实际上就是插入排序的递归算法。 2/22/2019

归并排序-2 把n个元素划分成两个子集合的另一种方法是将含有最大值的元素放入B,剩下的放入A中。然后A被递归排序。为了合并排序后的A和B,只需要将B添加到A中即可。 2/22/2019

归并排序-2 假如用函数Max来找出最大元素,这种排序算法实际上就是SelectionSort的递归算法。 2/22/2019

归并排序-3 假如用冒泡过程来寻找最大元素并把它移到最右边的位置,这种排序算法就是BubbleSort的递归算法。这两种递归排序算法的复杂性均为Θ(n2)。 若一旦发现A已经被排好序就终止对A进行递归分割,则算法的复杂性为O(n2) 2/22/2019

思考 采用平衡分割法? A集合中含有n/k 个元素,B中包含其余的元素。 2/22/2019

分而治之排序算法的伪代码 template<class T> void sort( T E, int n) { / /对E中的n 个元素进行排序, k为全局变量 if (n >= k) { i = n/k; j = n-i; 令A 包含E中的前i 个元素 令B 包含E中余下的j 个元素 sort( A , i ) ; sort( B , j ) ; merge(A,B,E,i,j,); //把A 和B 合并到E } else 使用插入排序算法对E 进行排序 2/22/2019

归并排序 k=2的排序方法被称为归并排序(merge sort),或更精确地说是二路归并排序(two-way merge sort)。 2/22/2019

归并排序 归并排序的平均复杂性为Θ(nlogn)。 2/22/2019

二路归并排序-2 另一种二路归并排序算法是这样的:首先将每两个相邻的大小为1的子序列归并,然后对上一次归并所得到的大小为2的子序列进行相邻归并,如此反复,直至最后归并到一个序列,归并过程完成。 通过轮流地将元素从a 归并到b 并从b 归并到a,可以虚拟地消除复制过程。 2/22/2019

二路归并排序-2 template<class T> void MergeSort(T a[], int n) {// 使用归并排序算法对a[0:n-1] 进行排序 T *b = new T [n]; int s = 1; // 段的大小 while (s < n) { MergePass(a, b, s, n); // 从a归并到b s += s; MergePass(b, a, s, n); // 从b 归并到a } 2/22/2019

MergePass函数 template<class T> void MergePass(T x[], T y[], int s, int n) {// 归并大小为s的相邻段 int i = 0; while (i <= n - 2 * s) { // 归并两个大小为s的相邻段 Merge(x, y, i, i+s-1, i+2*s-1); i = i + 2 * s; } // 剩下不足2个元素 if (i + s < n) Merge(x, y, i, i+s-1, n-1); else for (int j = i; j <= n-1; j++) // 把最后一段复制到y y[j] = x[j]; 2/22/2019

Merge函数 template<class T> void Merge(T c[], T d[], int l, int m, int r) {// 把c[l:m]] 和c[m:r] 归并到d [ l : r ] . int i = l, // 第一段的游标 j = m+1, // 第二段的游标 k = l; // 结果的游标 / /只要在段中存在i和j,则不断进行归并 while ((i <= m) && (j <= r)) if (c[i] <= c[j]) d[k++] = c[i++]; else d[k++] = c[j++]; // 考虑余下的部分 if (i > m) for (int q = j; q <= r; q++) d[k++] = c[q]; else for (int q = i; q <= m; q++) } 2/22/2019

归并排序 稳定排序? 2/22/2019

快速排序 n 个元素被分成三段(组):左段left,右段right和中段middle。中段仅包含一个元素。 左段中各元素都小于等于中段元素,右段中各元素都大于等于中段元素。因此left和right中的元素可以独立排序,并且不必对left和right的排序结果进行合并。 middle中的元素被称为支点(pivot)。 2/22/2019

快速排序 C.R.A.Hoare于1962年提出。 一旦知道某元素比基准值小,它就不必再与那些大的元素比较。同样,大的元素也不必与小的再比较。 2/22/2019

快速排序伪代码 //使用快速排序方法对a[0:n-1]排序 从a[0:n-1]中选择一个元素作为middle,该元素为支点 把余下的元素分割为两段left和right,使得left中的元素都小于等于支点,而right中的元素都大于等于支点 递归地使用快速排序方法对left进行排序 递归地使用快速排序方法对right进行排序 所得结果为left+middle+right 2/22/2019

例 考察元素序列[4,8,3,7,1,5,6,2]。假设选择元素6作为支点,则6位于middle;4,3,1,5,2位于left;8,7位于right。当left排好序后,所得结果为1,2,3,4,5;当right排好序后,所得结果为7,8。把right中的元素放在支点元素之后,left中的元素放在支点元素之前,即可得到最终的结果[1,2,3,4,5,6,7,8]。 2/22/2019

快速排序 template<class T> void QuickSort(T *a,int n) {//对a[0:n-1]进行快速排序 {//要求a[n]必需有最大关键值 quickSort(a,0,n-1);//支点在位置1 } 2/22/2019

快速排序 template<class T> void quickSort(T a[],int l,int r) {//排序a[l:r],a[r+1]有大值 if(l>=r)return; int i=l,//从左至右的游标 j=r+1;//从右到左的游标 T pivot=a[l];//支点 2/22/2019

快速排序 //把左侧>=pivot的元素与右侧<=pivot的元素进行交换 while(true){ do{//在左侧寻找>=pivot的元素 i=i+1; }while(a[i]<pivot); do{//在右侧寻找<=pivot的元素 j=j-1; }while(a[j]>pivot); if(i>=j)break;//未发现交换对象 Swap(a[i],a[j]); } 2/22/2019

快速排序 //设置pivot a[l]=a[j]; a[j]=pivot; quickSort(a,l,j-1);//对左段排序 quickSort(a,j+1,r);//对右段排序 } 2/22/2019

例 考察元素序列[4,8,3,7,1,5,6,2]。 2/22/2019

快速排序 快速排序的平均复杂性为Θ(nlogn)。 2/22/2019

快速排序 稳定排序? 2/22/2019

2/22/2019

各排序算法平均时间的曲线图 2/22/2019