演算法導論 7-6 對區間的模糊排序

來源:互聯網
上載者:User
一、題目

考慮這樣一種排序問題,即無法準確的知道等排序的各個數字到底是多大.對於其中的每個數字,我們只知道它落在實軸上的某個區間內.亦即,給定的 n 個形如[ai, bi ]的閉區間,其中ai,≤bi .演算法的目標是對這些區間進行模糊排序(fuzzy-sort),亦即,產生各區間的一個排序<i1, i2,
i3, i4,…in >,使得存在一個 cj ∈[ai, bi ],滿足c1≤c2≤…≤cn .a)       為n個區間的模糊排序設計一個演算法,你的演算法應該具有演算法的一般結構,它可以快速排序左部端點(即各ai ),也要能充分利用重疊區間來改善已耗用時間.(隨著各區間重疊得越來越多,對各區間的排序的問題會變得越來越容易,你的演算法應該能充分利用這種重疊.)b)      證明:
在一般情況下,你的演算法的區望已耗用時間為 O(n*lgn),但當所有的區間都重疊時,期望的已耗用時間為O(n) (亦即,當存在一個值 x, 使得對所有的 i, 都有x∈[ai, bi ] ).你的演算法不應顯式的檢查這種情況,而是應當隨著重疊量的增加,效能自然地有所改善.

二、思考

借用快排的劃分思路,以某個元素為主元,把地區劃分成三段,第一段都小於主元,第二段都等於主元

重點是劃分,區間如果重疊的部分,就把它們看做是相等的,並提取公用部分繼續劃分

a.end < b.start ==> a < b

a.start > b.end ==> a > b

其它情況 ==> a = b

為了避免類似於(2,2) (7,7) (1,8)這樣的情況,相等時要提取公因子,並更新主元(主元不一等是某個元素)

具體解釋都在代碼中


三、代碼

#include <iostream>using namespace std;struct node{int start;int end;bool operator<(const node & b)const{return end < b.start;}bool operator==(const node & b)const{return (end >= b .start) && (start <= b.end);}bool operator>(const node & b)const{return start > b.end;}};//劃分結果:0 -> a小於主元,a+1 -> b-1等於主元,b -> length_A大於主元struct divid{int a;int b;};node A[11];int length_A = 10;//按劃分結果分三行顯示void Print(divid d){int i = 1;if(d.a > 0){for(i = 1; i <= d.a; i++)cout<<'('<<A[i].start<<','<<A[i].end<<") ";cout<<endl;i = d.a + 1;}if(d.b > 0){for(; i < d.b; i++)cout<<'('<<A[i].start<<','<<A[i].end<<") ";cout<<endl;i = d.b;}if(i <= length_A){for(; i <= length_A; i++)cout<<'('<<A[i].start<<','<<A[i].end<<") ";cout<<endl;}cout<<endl;}//交換void Exchange(node &a, node &b){node temp;temp = a;a = b;b = temp;}//劃分是重點divid Partition(node *A, int p, int r){//先取任意一個元素為主元node x = A[r];int i = p-1, j = r+1, k = p;while(k <=r && k < j){//如果小於主元,交換到前面if(A[k] < x){i++;Exchange(A[i], A[k]);k++;}//如果大於,交換到後面else if(A[k] > x){j--;Exchange(A[j], A[k]);//這裡不能k++,因為交換過來的元素也可能大於主元}else{//如果相等,不交換,但是要提取公因子x.end = min(x.end, A[k].end);x.start = max(x.start, A[k].start);k++;}}//返回劃分結果divid ret = {i, j};if(ret.a < p)ret.a = -1;if(ret.b > r)ret.b = -1;Print(ret);return ret;}void QuickSort(node *A, int p, int r){if(p >= r)return;//把數組劃分為三段divid q = Partition(A, p, r);//如果存在第一段,對第一段排序if(q.a > 0)QuickSort(A, p, q.a);//如果存在第三段,對第三段排序if(q.b > 0)QuickSort(A, q.b, r);}int main(){int i, n;cin>>n;length_A = n;//init data by randomfor(i = 1; i <= length_A; i++){A[i].start = rand() % 100;A[i].end = rand() % 100;if(A[i].start > A[i].end)swap(A[i].start, A[i].end);}divid d = {-1, -1};Print(d);//sortQuickSort(A, 1, length_A);return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.