#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<set>
#include<random>
#pragma GCC optimize("Ofast")
using namespace std;
int rand_int(int a, int b);
void non_repeat(int n, int* a) {
set<int> s;
default_random_engine e(time(0));
while (s.size() != n) {
int m = e();
if (s.empty())
s.insert(m);
else if (s.find(m) == s.end())
s.insert(m);
}
int i = 0;
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
a[i++] = *it;
}
}
void shuffle(int n, int* a) {
for (int i = 0; i < n; i++)
a[i] = i;
for (int i = 0; i < n - 1; i++) {
int j = rand_int(i + 1, n - 1);
int tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
int rand_int(int a, int b) {
//产生a,a+1,a+2,...b的随机整数
default_random_engine e(time(0));
uniform_int_distribution<unsigned> u(a, b);
return u(e);
}
int search_x(int x, int i, int* ptr, int* val) {
while (x > val[i]) {
i = ptr[i];
}
return i;
}
int A(int x, int head, int* ptr, int* val) {
return search_x(x, head, ptr, val);
}
int D(int x, int head, int n, int* ptr, int* val) {
int m = rand_int(0, n - 1);
if (val[m] > x)
return search_x(x, head, ptr, val);
else if (val[m] < x)
return search_x(x, ptr[m], ptr, val);
else
return m;
}
int B(int x, int head, int n, int* ptr, int* val) {
int max_val = val[head];
int i = head;
int y = -1;
for (int j = 0; j < sqrt(n); ++j) {
y = val[j];
if (max_val < y && y <= x) {
i = j;
max_val = y;
}
}
return search_x(x, i, ptr, val);
}
int C(int x, int head, int n, int* ptr, int* val) {
int L = sqrt(n);
int* idx = new int[L];
default_random_engine e(time(0));
uniform_int_distribution<unsigned> u(0, n-1);
for (int i = 0; i < L; i++)
idx[i] = u(e);
int i = head;
int y = -1;
int max_val = val[i];
for (int j = 0; j < L; ++j) {
y = val[idx[j]];
if (max_val < y && y <= x) {
i = idx[j];
max_val = y;
}
}
delete []idx;
return search_x(x, i, ptr, val);
}
int main() {
int* val, * ptr, * a, n;
cout << "输入n:";
cin >> n;
ptr = new int[n];
val = new int[n];
a = new int[n];
shuffle(n, ptr);
non_repeat(n, a);
sort(a, a + n);
int head = ptr[0];
int k = head;
for (int i = 0; i < n; i++) {
val[k] = a[i];
k = ptr[k];
}
int i = head;
int m = 0;
while (1) {
m++;
i = ptr[i];
if (m == n - 1) {
ptr[i] = -1;
break;
}
}
cout << "************************" << endl;
while (1) {
cout << "输入i:";
cin >> i;
clock_t start = clock();
int k = 0;
int aa;
while(k++<100)
aa = A(val[i], head, ptr, val);
clock_t endA = clock();
k = 0;
int bb;
while(k++<100)
bb = B(val[i], head, n, ptr, val);
clock_t endB = clock();
k = 0;
int cc;
while (k++ < 100)
cc = C(val[i], head, n, ptr, val);
clock_t endC = clock();
k = 0;
int dd;
while (k++ < 100)
dd = D(val[i], head, n, ptr, val);
clock_t endD = clock();
double timeA = (double)(endA - start) / CLOCKS_PER_SEC;
double timeB = (double)(endB - endA) / CLOCKS_PER_SEC;
double timeC = (double)(endC - endB) / CLOCKS_PER_SEC;
double timeD = (double)(endD - endC) / CLOCKS_PER_SEC;
cout << "A:" << aa << " average time used is " << timeA/100 << endl;
cout << "B:" << bb << " average time used is " << timeB/100 << endl;
cout << "C:" << cc << " average time used is " << timeC/100 << endl;
cout << "D:" << dd << " average time used is " << timeD/100 << endl;
}
delete []a;
delete []ptr;
delete []val;
return 0;
}
A,B,C,D分别是最普通的算法(O(n))、时间复杂度为
n
\sqrt n
n的确定性算法,B的舍伍德算法形式以及普通的随机算法。
下图是一次运行结果:
可以看到,A,D的运行时间在同一个量级,时间复杂度为O(n),B,C的运行时间远远小于A,D,因为B,C的时间复杂度为
O
(
n
)
。
O(\sqrt n)。
O(n)。