您的位置:首页 > 编程语言 > C语言/C++

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

2011-01-27 10:32 162 查看
#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
;

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: