演算法導論第7章課後題(對區間的模糊排序)

來源:互聯網
上載者: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)這樣的情況,相等時要提取公因子,並更新主元(主元不一等是某個元素)

具體解釋都在代碼中


三、代碼

[cpp]
view plaincopyprint?
  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. struct node  
  5. {  
  6.     int start;  
  7.     int end;  
  8.     bool operator<(const node & b)const  
  9.     {  
  10.         return end < b.start;  
  11.     }  
  12.     bool operator==(const node & b)const  
  13.     {  
  14.         return (end >= b .start) && (start <= b.end);  
  15.     }  
  16.     bool operator>(const node & b)const  
  17.     {  
  18.         return start > b.end;  
  19.     }  
  20. };  
  21.   
  22. //劃分結果:0 -> a小於主元,a+1 -> b-1等於主元,b -> length_A大於主元
      
  23. struct divid  
  24. {  
  25.     int a;  
  26.     int b;  
  27. };  
  28.   
  29. node A[11];  
  30. int length_A = 10;  
  31.   
  32. //按劃分結果分三行顯示   
  33. void Print(divid d)  
  34. {  
  35.     int i = 1;  
  36.     if(d.a > 0)  
  37.     {  
  38.         for(i = 1; i <= d.a; i++)  
  39.             cout<<'('<<A[i].start<<','<<A[i].end<<") ";  
  40.         cout<<endl;  
  41.         i = d.a + 1;  
  42.     }  
  43.     if(d.b > 0)  
  44.     {  
  45.         for(; i < d.b; i++)  
  46.             cout<<'('<<A[i].start<<','<<A[i].end<<") ";  
  47.         cout<<endl;  
  48.         i = d.b;  
  49.     }  
  50.     if(i <= length_A)  
  51.     {  
  52.         for(; i <= length_A; i++)  
  53.             cout<<'('<<A[i].start<<','<<A[i].end<<") ";  
  54.         cout<<endl;  
  55.     }  
  56.     cout<<endl;  
  57. }  
  58. //交換   
  59. void Exchange(node &a, node &b)  
  60. {  
  61.     node temp;  
  62.     temp = a;  
  63.     a = b;  
  64.     b = temp;  
  65. }  
  66. //劃分是重點   
  67. divid Partition(node *A, int p, int r)  
  68. {  
  69.     //先取任意一個元素為主元   
  70.     node x = A[r];  
  71.     int i = p-1, j = r+1, k = p;  
  72.     while(k <=r && k < j)  
  73.     {  
  74.         //如果小於主元,交換到前面   
  75.         if(A[k] < x)  
  76.         {  
  77.             i++;  
  78.             Exchange(A[i], A[k]);  
  79.             k++;  
  80.         }  
  81.         //如果大於,交換到後面   
  82.         else if(A[k] > x)  
  83.         {  
  84.             j--;  
  85.             Exchange(A[j], A[k]);  
  86.             //這裡不能k++,因為交換過來的元素也可能大於主元
      
  87.         }  
  88.         else  
  89.         {  
  90.             //如果相等,不交換,但是要提取公因子   
  91.             x.end = min(x.end, A[k].end);  
  92.             x.start = max(x.start, A[k].start);  
  93.             k++;  
  94.         }  
  95.     }  
  96.     //返回劃分結果   
  97.     divid ret = {i, j};  
  98.     if(ret.a < p)ret.a = -1;  
  99.     if(ret.b > r)ret.b = -1;  
  100.     Print(ret);  
  101.     return ret;  
  102. }  
  103.   
  104. void QuickSort(node *A, int p, int r)  
  105. {  
  106.     if(p >= r)  
  107.         return;  
  108.     //把數組劃分為三段   
  109.     divid q = Partition(A, p, r);  
  110.     //如果存在第一段,對第一段排序   
  111.     if(q.a > 0)  
  112.         QuickSort(A, p, q.a);  
  113.     //如果存在第三段,對第三段排序   
  114.     if(q.b > 0)  
  115.         QuickSort(A, q.b, r);  
  116. }  
  117.   
  118. int main()  
  119. {  
  120.     int i, n;  
  121.     cin>>n;  
  122.     length_A = n;  
  123.     //init data by random
      
  124.     for(i = 1; i <= length_A; i++)  
  125.     {  
  126.         A[i].start = rand() % 100;  
  127.         A[i].end = rand() % 100;  
  128.         if(A[i].start > A[i].end)  
  129.             swap(A[i].start, A[i].end);  
  130.     }  
  131.     divid d = {-1, -1};  
  132.     Print(d);  
  133.     //sort   
  134.     QuickSort(A, 1, length_A);  
  135.     return 0;  
  136. }  
#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;}

 

轉載自:http://blog.csdn.net/mishifangxiangdefeng/article/details/7681109

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.