动态二分搜索器
来源:互联网 发布:深圳软件行业协会电话 编辑:程序博客网 时间:2024/06/07 10:10
算法导论的摊还分析章中的一道思考题,挺有意思的,2天以来用空闲时间写了下,debug亲测可运行。
//DynBinSearcher.h#ifndef DYNBINSEARCHER_#define DYNBINSEARCHER_template <class T>int binary_search(T key, T *arr, const int size){ int i = 0, j = size; int mid = 0; while (i < j){ mid = (i + j) / 2; if (key < arr[mid]){ j = mid; } else{ if (key > arr[mid]){ i = mid + 1; } else{ return mid; } } } return -1;}struct Pair{ Pair(int n_1, int n_2){ i = n_1; j = n_2; } int i; int j;};template <class T>/* Dynamic binary seacher* Brief: an improved version of binary search,* elements are partitioned into ⌈lg(n+1)⌉* sorted subarrays with size of 1, 2, 4, ..., 2^⌈lg(n+1)⌉,* Although each individual array is sorted, elements in* different arrays bear no particular relationship to each* other.* search: scan every subarrays from left to right, if* element is possibly in this subarray, then search it.* deletion: search the position of element, then take one* element from another subarray to replace it.* efficiency:* search: (worst case)lg(n)*lg(n)* insert: (worst case)O(n) (armotized cost)O(lg(n))* erase: (worst case)O(n) (armotized cost)O(lg(n))*/class DynBinSearcher{ template <class T> friend int binary_search(T, T *, const int);public: //IN ASSERTION: size != 0 DynBinSearcher(unsigned int size){ begin = 0; //calculation of total bits needed int i = 0; while ((size >>= 1) | 0){ i++; } num = i + 1; arrays = new T*[num]; //subarrays' space allocation for (; i >= 0; i--){ arrays[i] = new int[1 << i]; } //allocation for count begin = 0; full_bit = -1; extra_bit = -1; } ~DynBinSearcher(){ destroyArrays(); } Pair search(const T &); //bool search(const T &)const; void insert(const T &); bool erase(const T &);#ifdef TEST void output();#endifprivate: //helper function to destroy current arrays void destroyArrays(){ for (int i = 0; i < num; i++){ delete[]arrays[i]; } delete[]arrays; } //for code simplicity, return 0 when full_bit == -1, //2^full_bit otherwise. inline int full() { return (full_bit == -1) ? 0 : 1 << full_bit; } //return the size of a subarray. inline int size(int index) { if (index <= full_bit){ return 1 << index; } if (index < begin){ return full() + extra_bit + 1; } return full() + extra_bit; } //span space as twice bigger void grow(); T **arrays; int num; //begin: current subarray to insert int begin; //extra_bit: extra bits in subarray ayyays[begin]. int extra_bit; //full_bit: the rightest full subarray. int full_bit;};template <class T>Pair DynBinSearcher<T>::search(const T &x){ int i = 0, j = 0; while (i < num){ if (arrays[i][0] < x && x < arrays[i][size(i) - 1] && -1 != (j = binary_search(x, arrays[i], size(i))) ){ return Pair(i, j); } if (arrays[i][0] == x){ return Pair(i, 0); } if (arrays[i][size(i) - 1] == x){ return Pair(i, size(i) - 1); } i++; } //not found, set i = j = -1 return Pair(-1, -1);}template <class T>void DynBinSearcher<T>::insert(const T &x){ int i = 0; int size = full() + extra_bit; for (; i < size; i++){ if (arrays[begin][i] > x){ break; } } for (int j = size; j > i; j--){ arrays[begin][j] = arrays[begin][j - 1]; } arrays[begin][i] = x; //update parameters if (++begin == num){ if (++extra_bit == full()){ extra_bit = 0; if (++full_bit == num - 1){ //no free space now... //allocate twice memory grow(); } } begin = full_bit + 1; }}template <class T>bool DynBinSearcher<T>::erase(const T &x){ Pair pos(0, 0); pos = search(x); int i = pos.i, j = pos.j; if (i == -1){ //x not found return false; } if (--begin == full_bit){ if (extra_bit == 0){ full_bit--; extra_bit = full() - 1; } else{ extra_bit--; } begin = num - 1; } int filler = arrays[begin][size(begin)]; while (0 < j && filler <= arrays[i][j - 1]){ arrays[i][j] = arrays[i][j - 1]; --j; } while (j < size(i) - 1 && filler > arrays[i][j + 1]){ arrays[i][j] = arrays[i][j + 1]; ++j; } arrays[i][j] = filler; return true;}template <class T>void DynBinSearcher<T>::grow(){ //calculate new size int ol_size = num; int k = 1; while ((ol_size >>= 1) || 0) ++k; int more = (1 << k) - k - 1; k = num - k; //allocation T **new_array = new T *[num + more]; for (int s = 0; s < num + more; s++){ new_array[s] = new T[1 << s]; } //initialization int j = 0; for (; j <= k; j++){ for (int p = 0; p < size(j); p++){ new_array[j][p] = arrays[j][p]; } } for (; j < num; j++){ for (int p = 0; p < (1 << k); p++){ new_array[j][p] = arrays[j][p]; } } int i = k + 1; for (; i < num; i++){ int r = 1 << k; for (int n = 0; n < (1 << (i - k)) - 1; n++, j++){ for (int m = 0; m < (1 << k); m++, r++){ new_array[j][m] = arrays[i][r]; } } } //reset arrays destroyArrays(); arrays = new_array; //update parameters num += more; begin = k + 1; extra_bit = 0; full_bit = k;}#ifdef TESTtemplate <class T>void DynBinSearcher<T>::output(){ for (int i = 0; i < num; i++){ for (int j = 0; j < size(i); j++){ cout << setw(4) << arrays[i][j]; if ((1 + j) % 16 == 0){ cout << endl; } } cout << "\n--------------------------------" << i << "--------------------------------\n"; } cout << endl;}#endif#endif
//DynBinSearcher_test.cpp#include <iostream>#include <iomanip>#include <ctime>using namespace std;#define TEST 1#define DATA_SIZE 400#include "DynBinSearcher.h"#include "ArrayQueue.h"int main(){ srand(time(0)); DynBinSearcher<int> dbs(10); ArrayQueue<int> recorder(DATA_SIZE); //insertion test for (int i = 0; i < DATA_SIZE; i++){ if (i == 50){ dbs.insert(19); recorder.enqueue(19); continue; } int x = rand() % 100 + 1; recorder.enqueue(x); dbs.insert(x); /* cout << "insert(" << x << ")" << endl; dbs.output();*/ } dbs.output(); //search test Pair p_19 = dbs.search(19); cout << "search 19: " << "(" << p_19.i << "," << p_19.j << ")" << endl; //deletion test for (int i = 0; i < DATA_SIZE; i++){ int x = recorder.front(); if (!dbs.erase(x)) cout << "ERROR: " << x << "NOT FOUND\n"; recorder.dequeue(); } cout << "clear." << endl; dbs.output(); return 0;}
0 0
- 动态二分搜索器
- 动态数组 选择排序 二分搜索技术
- 二分搜索(vector动态输入)
- POJ 2533 最长上升子序列 [动态规划 + 二分搜索]
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 二分搜索
- 关于IE8兼容的一些问题
- Eclipse中不使用内嵌Maven
- 5题
- ios实现加载框
- 随机数random()
- 动态二分搜索器
- 截取一个字符串中的所有数字并输出
- java中,只声明一个对象不赋值,与声明一个对象并赋为null,有啥区别?
- [iOS Xocd8] Xcode8 10大新特性
- 文章标题
- session高级(session入库)
- 使用Maven构建Web项目
- 第一本十五章买家电
- C#小程序实现闰年判断、月份的天数以及所属季度的判断(完善1)