区间模糊排序---快排思路的应用

  1 #include<iostream>
  2 #include<ctime>
  3 using namespace std;
  4 #define max(a,b) (a>b)?a:b
  5 #define min(a,b) (a>b)?b:a
  6 class Interval
  7 {
  8 public:
  9     double leftbound;
 10     double rightbound;
 11     Interval(int a, int b) :leftbound(a), rightbound(b){}
 12     Interval(Interval &i){ leftbound = i.leftbound; rightbound = i.rightbound; }
 13     Interval(){}
 14 };
 15 void swap(Interval &a, Interval &b)
 16 {
 17     Interval temp = a;
 18     a = b;
 19     b = temp;
 20 
 21 }
 22 void display(Interval a[], int begin, int end)
 23 {
 24     for (int i = begin; i <= end; ++i)
 25         cout << "[" << a[i].leftbound << "," << a[i].rightbound << "]" << ",";
 26     cout << endl;
 27 }
 28 void partition(Interval a[], int begin, int end, int &ini, int &ter)   //参数ini、ter是引用,是为了作为返回值
 29 {
 30 
 31     Interval pivot = a[begin];        //主元区间
 32     ini = begin;
 33     ter = end + 1;            //注意,这里ter从数组外部开始
 34 
 35     int cur = begin + 1;
 36     while (cur < ter && cur<end)
 37     {
 38         if (a[cur].rightbound <= pivot.leftbound && ini<end)        //小于主元区间
 39         {
 40             ++ini;
 41             swap(a[cur], a[ini]);
 42             ++cur;
 43             //cout << "1: ";
 44             //display(a, begin, end);
 45         }
 46         else if (a[cur].leftbound >= pivot.rightbound && ter>begin) //大于主元区间
 47         {
 48             --ter;
 49             swap(a[cur], a[ter]);
 50             //cout << "2: ";
 51             //display(a, begin, end);
 52 
 53         }
 54         else            //和主元区间相等, 所以取交集作为新的主元
 55         {
 56             pivot.leftbound = max(pivot.leftbound, a[cur].leftbound);
 57             pivot.rightbound = min(pivot.rightbound, a[cur].rightbound);
 58             //cout << "pivot: " << pivot.leftbound<<" ,"<<pivot.rightbound << endl;
 59             ++cur;
 60             //cout << "3: ";
 61             //display(a, begin, end);
 62         }
 63     }
 64     swap(a[ini], a[begin]);    //调整
 65 
 66     --ini;
 67     //cout << "ini: " << ini <<"  "<< "ter: " << ter << endl;
 68     //display(a, begin,end);
 69 
 70 
 71 }
 72 void fuzzySortingOfInterval(Interval a[], int begin, int end)
 73 {
 74     if (begin < end)
 75     {
 76         int ini, ter;
 77         partition(a, begin, end, ini, ter);
 78         fuzzySortingOfInterval(a, begin, ini);
 79         fuzzySortingOfInterval(a, ter, end);
 80     }
 81 }
 82 int main()
 83 {
 84     srand(time(NULL));
 85     const int size = 8;
 86     Interval a(28508, 31359), b(4712, 30466), c(23267, 30245), d(7134, 8098), e(25400, 26351), f(8079, 29052), g(31163, 31738), h(6346, 24352);
 87     Interval array[size] = { a, b, c, d, e, f, g, h };
 88     Interval *array = new Interval[size];
 89     for (int i = 0; i < size; ++i)
 90     {
 91     array[i].leftbound = rand() % 100;
 92     array[i].rightbound = rand() % 100;
 93     while (array[i].rightbound < array[i].leftbound)
 94     array[i].rightbound = rand() % 100;
 95     }
 96     display(array, 0, size - 1);
 97     fuzzySortingOfInterval(array, 0, size - 1);
 98     display(array, 0, size - 1);
 99     system("pause");
100 }

关于算法呢,其实很简单,区间的比较结果有三种:小于,等于(有交集),大于,这里的优化在于,每次有等于情况时都取交集作为新的主元,这样的好处在于:扩大中间等于的区域,减少递归深度。

关于代码呢,这里partition函数我们要返回一个区间,是要返回其左右的数字,而C++只能有一个返回值,因此这里借助了引用返回的技巧来实现,另一方面,我们可以借助STL 的pair类型

pair<int,int>& partition(int begin,int end)

{  
  .....

  

  return pair<int,int>(ini,ter);

}

调用时  ini=partiton(begin,end).first;ter=partition(begin,end).second;

原文地址:https://www.cnblogs.com/gaoduan/p/3893516.html