中值问题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;
}
#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;
}
相关文章推荐
- 算法面试题1:约瑟夫问题(c++实现方式)
- 八皇后问题C++泛型算法实现
- 【刘庆源码共享】稀疏线性系统求解算法 之 高斯-塞德尔算法(Gauss_Seide)GS类定义(C++)
- 较高人工智能的人机博弈程序实现(多个算法结合)含C++源码
- C++基础算法学习——N皇后问题
- c++实现0-1背包问题完整源码(动态规划实现)
- 最大流问题-Ford-Fulkerson算法 C++极简实现
- 经典面试问题:12小球问题算法(源码)
- 经典算法---8皇后问题的C++实现
- 算法导论 第16章 贪心算法-活动选择问题C++实现
- 【C/C++】C语言复习笔记-17种小算法-解决实际问题
- 算法笔记之黑匣子问题(c++实现)
- 整数取反问题的算法实现(C/C++实现,极简5行代码)
- 经典面试问题:12小球问题算法(源码)
- 【高级算法】禁忌搜索算法解决3SAT问题(C++实现)
- [C++] cout、wcout无法正常输出中文字符问题的深入调查(2):VC2005的crt源码分析
- 【高级算法】模拟退火算法解决3SAT问题(C++实现)
- C/C++面试之算法系列--约瑟夫环:每隔两个循环删除数组元素,求最后删除者的下标问题
- 【高级算法】模拟退火算法解决3SAT问题(C++实现)
- 经典面试问题:12小球问题算法(源码)