算法-分块/索引查找

分块/索引查找

  • 思路
前提: 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;
}

你可能感兴趣的:(算法,算法)