中值问题O(N)算法C++源码

来源:互联网 发布:阿里云服务器升级配置 编辑:程序博客网 时间:2024/05/22 15:34

 

#include <iostream>

#include <cstdlib>

#include <ctime>

#include <algorithm>

using namespace std;

 

void swap(int A[], int i, int j) {

       if (i != j) {

            int t = A[i];

            A[i] = A[j];

            A[j] =t;

      }

}

 

int partition(int A[], int p, int r) {

    int x = A[r];

    int i = p - 1;

    for (int j = p; j <= r-1; j++) {

          if (A[j] <= x) {

                i++;

                swap(A, i, j);

          }

     }

 

     swap(A, i+1, r);

     return i+1;

}

 

int randomized_partition(int A[], int p, int r) {

     srand(time(NULL));

     int i = p + rand() % (r-p+1);

     swap(A, i, r);

     return partition(A, p, r);

}

 

int randomized_select(int A[], int p, int r, int i) {

    if (p == r) 

    return A[p];

    int q = randomized_partition(A, p, r);

    int k = q - p + 1;

    if (i == k)

         return A[q];

    else if (i < k)

         return randomized_select(A, p, q-1, i);

    else 

         return randomized_select(A, q+1, r, i-k);

}

 

void triplet_adjust(int A[], int i, int step) {

    int j = i + step;

    int k = i + 2 * step;

    if (A[i] < A[j]) {

    if (A[k] < A[i])

swap(A, i, j);

    else if (A[k] < A[j])

        swap(A, j, k);

    }

    else {

if (A[i] < A[k])

             swap(A, i, j);

else if (A[k] > A[j])

             swap(A, j, k);

     }

}

 

double mean(int A[], int n) {

      double f = A[0];

      for (int i = 1; i < n; i++)

             f += A[i];

      return f / n;

}

 

int approximate_median(int A[], int r) {

     int step = 1;

     int size = 1;

     int i;

 

    for (int j = 0; j < r; j++)

          size *= 3;

    for (int k = 0; k < r; k++) {

          i = (step - 1) / 2;

          while (i < size) {

                 triplet_adjust(A, i, step);

                 i += (3 * step);

          }

          step *= 3;

      }

 

      return A[(size-1)/2];

}

 

void selection_sort(int A[], int left, int size, int step) {

      int min;

      int i, j;

      for (i = left; i < left + (size-1) * step; i += step) {

              min = i;

              for (j = i+step; j < left + size; j += step) {

                     if (A[j] < A[min])

                     min = j;

              }

              swap(A, i, j);

        }

}

 

const int SORT_NUM_THRESHOD = 50;

 

int approximate_median_any_n(int A[], int size) {

      bool left_to_right = false;

      int left = 0;

      int step = 1;

      int i;

     while (size > SORT_NUM_THRESHOD) {

            left_to_right = !left_to_right;

            int rem = size % 3;

            if (left_to_right)

                   i = left;

            else

                   i = left + (3 + rem) * step;

            for (int j = 0; j < (size / 3 - 1); j++) {

                  triplet_adjust(A, i, step);

                  i += 3 * step;

            }

 

        if (left_to_right) 

             left += step;

        else {

             i = left;

             left += (1 + rem) * step;

        }

  

         selection_sort(A, i, 3 + rem, step);

 

         if (rem == 2) {

               if (left_to_right)

                       swap(A, i+step, i+2*step);

               else

                      swap(A, i+2*step, i+3*step);

           }

 

            step *= 3;

             size = size / 3;

}

 

selection_sort(A, left, size, step);

       return A[left + step * int( (size-1) / 2 )];

}

 

 

int main(int argc, char* argv[]) 

{

    const int DEFAULT_N = 1000000;

    int N;

 

      if (argc < 2) {

            N = DEFAULT_N;

     }

     else {

            N = atoi(argv[1]);

     }

 

cout << "N = " << N << endl;

clock_t t = clock();

cout << clock() << endl;

int* A = new int[N];

cout << clock() << endl;

srand(time(NULL));

for (int i=0; i<N; i++) {

A[i] = rand() % N;

}

 

clock_t t1 = clock();

cout << t1 << endl;

double avg = mean(A, N);

cout << avg << endl;

 

clock_t t2 = clock();

cout << t2 << endl;

int m = approximate_median_any_n(A, N);

cout << m << endl;

 

clock_t t3 = clock();

cout << t3 << endl;

m = randomized_select(A, 0, N-1, N/2);

cout << m << endl;

 

clock_t t4 = clock();

cout << t4 << endl;

 

std::sort(A, A+N);

m = A[N/2];

cout << m << endl;

 

clock_t t5 = clock();

cout << t5 << endl;

 

cout << endl;

 

double dt = (double) (t2-t1) / CLOCKS_PER_SEC;

cout << dt << "  " ;

dt = (double) (t3-t2) / CLOCKS_PER_SEC;

cout << dt << "  " ;

dt = (double) (t4-t3) / CLOCKS_PER_SEC;

cout << dt << "  " ;

dt = (double) (t5-t4) / CLOCKS_PER_SEC;

cout << dt << "  " ;

   cout << endl;

 

}

 

原创粉丝点击