有序表搜索

    科技2024-11-05  19

    #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 )

    Processed: 0.011, SQL: 8