收藏 分享(赏)

分治算法举例.doc

上传人:精品资料 文档编号:9970409 上传时间:2019-09-23 格式:DOC 页数:4 大小:19.60KB
下载 相关 举报
分治算法举例.doc_第1页
第1页 / 共4页
分治算法举例.doc_第2页
第2页 / 共4页
分治算法举例.doc_第3页
第3页 / 共4页
分治算法举例.doc_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

1、1 设 X0:n-1和 Y0:n-1为两个数组,每个数 组中含有 n 个已排序好的数。试设计一个 O(logn)时间的分治算法,找出 X 和 Y 的 2n 个数的中位数,并 证明算法的时间复杂性为 O(logn)。注:个数为奇数,则处于最中间位置的数;个数为偶数,则中间两个数据的平均数。解:利用二分查找思想:对于两个等长的数组,如果数组长度为奇数,令 mid 为数组的最中间元素的位置,则有 Xmid,Ymid分别为两个数组的中位数,则存在以下情况:(1)如果 XmidYmid,则两个数 组合并后的中位数应该在 X0 : mid和 Ymid : n-1中查找;(3)如果 Xmid=Ymid,则两

2、个数 组合并后的中位数就是 Xmid或者 Ymid另外考虑特殊情况:如果两个数组的长度为 1,则无需比较 大小,合并后数 组的中位数即为两个数组元素的平均值。如果数组的长度为偶数,令 mid 为数组的中间两个元素的较小元素的位置,此时数组 X 的中位数为 x=(Xmid+Xmid+1)/2.0,数组 Y 的中位数为 y=(Ymid+Ymid+1)/2.0 (这里考虑到中位数不一定为整数)。则存在以下情况:(1)如果 xy,则两个数组合并后的中位数应该在 X0 : mid和 Ymid+1 : n-1中查找;(3)如果 x=y,则两个数组合并后的中位数就是 x 或者 y.考虑特殊情况:如果两个数组

3、的长度为 2,则如果其中一个数 组 A 的元素刚好处于合并后的数组的中间位置,则最终的中位数 为这个数组 A 的数组元素的平均数。否则, 则回到数组长度为偶数的一般情况。具体如下:double Search_Median(int *A,int l1,int r1,int *B,int l2,int r2,int n)/*如果两个数组的长度为,则中位数为所有元素的平均数,其中A,B为要查中位数的数组,l1,r1,l2,r2分别为两个数组每次查询的起始位置和终点位置n为两个数组每次查询时的范围(重新查询的数组长度)*/if (n=1) /数组长度为1的情况return (Al1+Bl2)/2.0;

4、if (n=2) /数组长度为2的情况if (Al1Bl1else;/这里使用mid1,mid2分别来记录两个数组每次变化后的中间位置int mid1=(r1+l1)/2;int mid2=(r2+l2)/2;/如果数组的长度为偶数,对数组进行查询if(n%2=0)/这里考虑到偶数数组的中位数是中间两个数的平均数double x=(Amid1+Amid1+1)/2.0;double y=(Bmid2+Bmid2+1)/2.0;if (x ( , )使用分治方法求整个序列中逆序对个数,并分析算法的时间复杂性。例如:序列(4, 3, 2)逆序对有(4, 3),(4, 2),(3, 2)共 3 个解

5、:数据输入:a 数组,n(元素个数)采用归并排序思想:将序列看成一个数组假设 f(i , j)为 i 到 j 的逆序对 个数,取一个分割点 k,假 设 s(i , j , k)表示以 k 为分割点,第一个元素在 i 到 k 中,第二个元素在 k+1 到 j 中形成的逆序对数。那么可以形成一个递归式:f(i , j)=f(i , k) + f(k+1 , j) + s(i , j , k).采用归并排序算法进行递归求解,如果对于 A 数组的 i 到 k 和 k+1 到 j 两个部分皆为有序的情况,那么对于当 ajai时,必然有 ajaik,即 aj和从 i 到 k 号元素都形成逆序对,此时只要将

6、 s(i,j,k)加上 k-i+1(i到 k 之间的元素个数)就可以了,此过程类似于归并排序的合并过程。 则可以据此得到相应算法。首先设置一个计数器记录逆序对个数,每次 归并分成分割与合并两部分,在合并部分中过程中添加计数过程,具体如下:static int count=0; /定义一个 计数器, 记录逆序对个数void merge(int a,int p,int q,int r)/合并过程,其中a 为原数组,p为数组的起始位置,q为分割位置,r为元素个数int n1=q-p+1;int n2=r-q; /定义两个新数组存放数组a中的元素int * l=new intn1+1; int * r

7、l=new intn2+1; for(int i=0;in1;i+) li=ap+i-1; for(int j=0;jn2;j+) rlj=aq+j; ln1=65535; /将新数组的最后一个位置设为无限大作为哨兵rln2=65535; int i=0; int j=0; /合并两个数组到原数组for(int k=p-1;kr;k+) if(li=rlj) ak=li;i+; else ak=rlj; j+; count+=(q-i+1-p);/存在逆序对,将逆序对数进行记录 void mergeSort(int a,int p,int r) /分割过程,r为元素个数if(pr) int q=(p+r)/2; mergeSort(a,p,q); mergeSort(a,q+1,r); merge(a,p,q,r); 时间复杂度分析:因为记录的过程是随着归并排序的过程处理的,仅仅在合并到原数组的过程中添加一条语句,用于记录。因此算法的时间复杂度为 O(nlogn)。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报