- 1、本文档共40页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
2013算法整理
证明:基于比较的排序算法平均时间复杂度=O(nlogn) 与最坏时间复杂度=O(nlogn) 。比较排序可以被抽象的视为判定树。要使排序算法正确地工作,其必要条件是,n个元素的n!种排列中的每一种都要作为判定树的一个叶子而出现。对于n个元素来说,判定树的叶子树为n!,其高度对应最深叶子的深度,而最深叶子的深度对应最坏时间,即若要证明最坏时间复杂度= O(nlogn),就要证明判定树高度 =O(nlogn)。由二叉树的性质,深度为h的二叉树,最多有2h个叶子节点,因而叶子数为n!的判定树高度= log(n!)。所以比较排序的最坏时间W(n) 判定树的最大高度 log(n!)。即W(n)= log(n!)= log(n) + log(n-1)+log(n-2)+...+log2+log1=log(n)+log(n-1)+log(n-2)+...+log(n/2)=(n/2)log(n/2)=(n/2)log(n)-n/2=O(nlogn)比较排序的平均时间A(n) 判定树的平均叶子深度。判定树的平均叶子深度叶子数为n!,高度=log(n!)Logn!-1高度,其叶子数至多为2logn!-1 =n!/2 缩放: 将高度logn!的叶子节点(n!/2个)的高度都缩放为0剩余n!/2个叶子的高度均为log(n!)归并排序的复杂度分析及优化措施1.复杂度分析在最坏的情况下,n个元素合并,比较次数为n-1次因此W(n)=W[n/2]+W[n/2]+n-1 其中W(1)=0W(n) = 2W(n/2)+n-1= 2(2W(n/4)+n/2-1)+n-1= 4W(n/4)+2n-2-1 递归迭代K次 其中k=logn (n= 2k )W(n)=2k W(n/ 2k)+kn-(1+2+3…+ 2k-1)W(n)=nW(1)+nlogn-(n-1)W(n)=nlogn-(n-1)因此归并排序的时间复杂度为O(nlogn)归并排序的优化措施1.不回写2.不递归3.与插入相结合4.无逆序(对相对有序的序列来说,可以将有序的部分合为一个集合,减少比较次数)具体改进的算法描述:A.将原数据集合分成若干组,分组策略如下:第一组:从第1个元素a1 开始到第20个元素a20 ,用插入排序排成有序集,从第21个元素起,按无逆序原则向后找到第一个出现逆序的元素ak 为止。那么第一组的元素为 ,a1 …a20 …ak .(插入排序平均时间复杂度为O(n^2/4)当n=16时,插入优于归并)第二组:从 ak开始按照找第一组的方法,找出第二组;第三组、第四组……依次类推。按此方法将数据集分成若干组,在分组的过程中体现出与插入排序相结合和无逆序的改进。B.对划分的组进行如下处理:假定初始的元素存放在数组A中,申请同样大存储空间的数组B。奇数趟归并排序时(此时元素存储在数组A中),两两相邻的分组归并后存放到数组B。偶数趟归并排序时(此时元素存储在数组B中),两两相邻的分组归并后存放到数组A。重复上述操作,直到最后归并到成一个集合为止。按此方法对组进行归并排序,体现了不回写和不递归的改进。void InsertSort(int* a, int n){ for (int i = 1; i n; ++i) { int j; int tmp = a[i]; for (j = i - 1; j = 0; --j) if (tmp a[j]) a[j + 1] = a[j]; else break; a[j + 1] = tmp; }}//与插入相结合 不递归 不回写//如果想实现无逆序会使得各个块的大小不相同因此必须新加一个数组记录各个块的起始位置,这样做得不偿失 所以暂时无法加入无逆序的优化void MergeSort(int* arr, int n){ int tmp[Maxn]; for (int i = 0; i n; i += 16)//小于16 采用插入排序 InsertSort(arr + i, min(n - i, 16)); for (int i = 16; i n; i = 1) //归并的单个块大小 { //s表示第一块归并起点,a表示第一个块处理完的大小, b表示第二个块处理完的大小 s+i 表示第二块归并起点 int s, a, b; //两块有序集合进行合并 奇数次归并 从左向右 for (a = 0, b = 0, s = 0; s n; s += (i 1), a = 0, b = 0) //第一块起始位置 { int la = min(s + i, n) - s; int lb = min(s + i + i, n) - (s + i); int cnt = 0; while (a la || b lb)//归并 { while
您可能关注的文档
最近下载
- 2022急诊胸痛心血管标志物联合检测专家共识(全文).pdf VIP
- 2025年四川高处安装、维护、拆除作业_特种作业证考试复习题库资料(含答案).pdf
- 临床医学专业水平测试评分表.pdf VIP
- 2024年四川省绵阳市中考化学真题卷(含答案与解析).pdf VIP
- 《三位数乘两位数》大单元教学设计 (1).docx VIP
- 2024年四川省绵阳市中考数学真题卷(含答案与解析).pdf VIP
- 生如夏花小清新模板(含音频+视频).pptx VIP
- 2024学年统编版高中语文选择性必修下册《客至》优质课一等奖课件28张.pptx
- Sysmex XN-1000全自动血液分析仪标准操作程序.pdf VIP
- 2025安全生产月主题宣讲课件.pptx
文档评论(0)