【算法导论笔记】模糊排序7-6

来源:互联网 发布:春纪护肤品怎么样知乎 编辑:程序博客网 时间:2024/05/22 16:07

为什么要单独拿出来记录呢,前面不是已经更新了一篇关于排序的文章了么。其实是因为在这里我浪费了很多很多时间,最近智商有点拙计,把这个独成文以引起自己现在状态的正视。

7-6、考虑这样的一种排序问题,即无法准确地知道待排序的各个数字到底是多少。对于其中的每个数字,我们只知道它落在实轴上的某个区间内。亦即,给定的是n个形如[a(i), b(i)]的闭区间(这里小括后起下标的作用,后同),其中a(i) <= b(i)。算法的目标是对这些区间进行模糊排序(fuzzy-sort),亦即,产生各区间的一个排列<i(1), i(2), ..., i(n)>,使得存在一个c(j)属于区间[a(i(j)), b(i(j))],满足c(1) <= c(2) <= c(3) <= ... <= c(n)。

a) 为n个区间的模糊排序设计一个算法。你的算法应该具有算法的一般结构,它可以快速排序左部端点(即各a(i)),也要能充分利用重叠区间来改善运行时间。(随着各区间重叠得越来越多,对各区间进行模糊排序的问题会变得越来越容易。你的算法应能充分利用这种重叠。)

b) 证明:在一般情况下,你的算法的期望运行时间为Θ(nlgn),但当所有的区间都重叠时,期望的运行时间为Θ(n)(亦即,当存在一个值x,使得对所有的i,都有x∈[a(i), b(i)])。你的算法不应显式地检查这种情况,而是应随着重叠量的增加,性能自然地有所改善。
算法思路:是个划分区间的过程,这样说可能会引起误解,其实是把每个区间看作是一个数组元素,对于两个区间[ai,bi],[aj,bj]关于他们的大小关系如下;

1)、bi < aj,则认为区间i小于区间j;

2)、bj < ai则认为区间i 大于区间j;

3)、有交集则认为两个区间相等。

有了这个关系就可以对区间排序应用快排了,关键点是如何利用重叠空间改善运行时间。做法是在快排中一个元素与主元比较是去,练个元素的公共区间继续进行算法,说是这样说但为什么呀。。。。。先看下面的算法步骤。

1、设A[n]数组作为输入数组,其中每个元素代表一个区间,对于数组A[p,r]把数组分为三个这样的数组A[p,s]、A(s,t)、A[t,r],注意中间数组为开区间。对于这三个数组有:中间区间的元素两两都有交集,满足模糊排序要求,“存在一个····”;设在一次划分后,中间区间所有元素的交集为elem,左区间里面的元素严格小于(也就是上面关系的第一种)elem,右区间每个元素必须满足严格大于elem;

2、递归对左右区间进行模糊排序,由于结合1可以得出整个A[p,r]有序,模糊排序完成。

对于为什么要取公共区间再继续算法的问题:缩小主元的区间大小,有利于增加中间数组A(s,t)元素的个数,也就是减少左右区间元素的个数,这样递归深度得到减少,当然这都是建立在一般情况下的分析。最后源代码参上(写代码是各种sb行为,简直想抓自己暴打一顿):

//输出区间void OutputInterval( interval arr[], int beg, int end ){for( int i = beg ; i <= end ; i++ ){cout <<'<' <<arr[i].a  <<"," <<arr[i].b <<'>' <<' ';}cout <<endl;}//划分区间数组,把区间数组划分为三个部分:[iBeg,rBeg],(rBeg,rEnd),[rEnd,iEnd];void FuzzyPartition( interval arr[], int iBeg, int iEnd, int& rBeg, int &rEnd ){//OutputInterval( arr, iBeg, iEnd );int i = iBeg-1;int j = iEnd+1;interval key = arr[iEnd];for(int k = iBeg; k < j && k <= iEnd; k++){if(arr[k].b < key.a){//第k个区间严格小于主元i++;swap(arr[k], arr[i]);}else if( arr[k].a > key.b ){//第k个区间严格大于主元j--;swap( arr[k], arr[j] );k--; //因为并不能保证新交换过来的区间严格小于主元}else{key.a = max( arr[k].a, key.a );key.b = min( arr[k].b, key.b );}//cout <<j <<' ';}//cout <<key.a <<' ' <<key.b <<endl;//OutputInterval( arr, iBeg, iEnd );//cout <<endl;rBeg = i;rEnd = j;}void FuzzySort( interval arr[], int beg, int end ){while(beg < end){int rBeg,rEnd;rBeg = rEnd = 0;FuzzyPartition( arr, beg, end, rBeg, rEnd );FuzzySort( arr, beg, rBeg );beg = rEnd;}}

THE END~~~~~

原创粉丝点击