分块/索引查找
- 思路
前提: 1.块间有序 2.块内可以无序 3.索引中保存块的起始地址,和块内的最大值或者最小值
首先对索引进行折半查找,然后对块内进行顺序查找。
- 算法复杂度
假设一个n长度的数组分为m块,每块的长度为: n/m, 那么算法的平均复杂度:O(n) = logm+n/m, 算法最坏情况下的复杂度: O(n) = logm + n/m。
cpp实现
struct block {
int bindex;
int blen;
int bmax;
int* belements;
};
int Partition(int arr[], int start, int end) {
int pivot = arr[start];
int highvac = end;
int lowvac = start;
int direct = true; //true for right,false for left. start from left
while(lowvac < highvac) {
if(direct == true) {
if(arr[highvac] <pivot) {
arr[lowvac] = arr[highvac];
lowvac++;
direct = false;
} else {
highvac--;
}
} else {
if(arr[lowvac] > pivot) {
arr[highvac] = arr[lowvac];
highvac--;
direct = true;
} else {
lowvac++;
}
}
}
arr[highvac] = pivot;
return highvac;
}
int findXMaxValue(int arr[], int xmax, int start, int end) {
int p = 0;
int cmax = end - start +1;
int len = end;
if (xmax >= len+1) {
return p;
}
while(cmax != xmax) {
p = Partition(arr,start,end);
cmax = len-p+1;
if(cmax > xmax) {
start = p+1;
} else if ( cmax < xmax) {
end = p-1;
start = 0;
}
}
return p;
}
//find the max value
int findMaxValue(int arr[], int start, int end) {
int max = arr[start];
int len = end - start+1;
for(int i = 0; i < len; i++) {
if(max < arr[i]) {
max = arr[i];
}
}
return max;
}
int blockIndexSearch(block dest_arr[], int search, int array_size) {
//search the block index by binarysearch at first
int left = 0;
int right = array_size -1;
while(left <= right){
int amid = (right+left)/2;
int bmax = dest_arr[amid].bmax;
if (search > dest_arr[amid].bmax) {
left = amid +1;
} else {
//order search in block
int* belements = dest_arr[amid].belements;
int blen = dest_arr[amid].blen;
int bindex = dest_arr[amid].bindex;
for(int i = 0; i< blen; i++) {
if(search == belements[i]) {
return i+bindex;
} else {
i++;
}
}
right = amid-1;
}
}
return -1;
}
//generate blockIndex
block* blockIndex(int dest_arr[],int block_num, int array_size) {
static block* block_arr = new block[block_num];
int block_size = array_size/block_num;
int block_indexes[block_num];
int csize = array_size;
for( int i = 0; i < block_num-1 && csize > block_size; i++) {
int p = findXMaxValue(dest_arr,block_size, 0, csize-1);
csize = csize-block_size;
//cout << "Xmax position:" << p << endl;
block_indexes[i] = p;
}
block_indexes[block_num-1] = 0;
printArray(block_indexes,block_num);
//generate block-indexed array
for(int j = block_num -1; j >= 0; j--) {
int bindex = block_indexes[j];
int bend = array_size;
if (j != 0) {
bend = block_indexes[j-1];
}
int blen = bend - bindex;
int* belements = new int[blen];
for(int i = 0; i < blen; i++ ) {
belements[i] = dest_arr[bindex+i];
}
int bmax = findMaxValue(belements,0,blen-1);
struct block tblock = {bindex,blen,bmax, belements};
int index = block_num-1-j;
block_arr[index] = tblock;
}
return block_arr;
}