二分查找、two points、排序

二分查找

1、查找某元素。循环条件 low <= high,最终结果位mid, 如果查询失败则返回-1。

int binSearch(int num[], int low, int high, int x){
    int mid;
    while(low <= high){ //当搜索区间为空时结束
        mid = low + (high - low) / 2;
        if(num[mid] == x)
            return mid;
        else if(num[mid] > x)
            high = mid - 1;
        else low = mid + 1;
    }    
    return -1;
}

2、查找第一个满足条件的元素。

     1)被排好序的待搜索序列一定是从左到右先不满足条件,然后满足条件; 

     2)传入的high = N时,在搜索不到满足条件的数时,会返回N(假想N位置有数字); 若不想传入N,则需要在函数刚进入就判断,最后一个元素是否不满足条件,若不满足则说明查找失败,返回-1。

     3)返回的是low而不是mid。

     4)最后一个小于x的元素,相当于查找第一个大于等于x的元素的前一个。

/*返回第一个大于等于x的元素。num[N]数组应从小到大排序。
如果传入的high = N,则当序列中所有元素都小于x时,会返回N */
int binSearch(int num[], int low, int high, int x){
    int mid;
    while(low < high){  //当low == high时结束搜索
        mid = low + (high - low) / 2;
        if(num[mid] >= x)
            high = mid;  //mid有可能就是结果,所以区间上限不能漏掉mid
        else low = mid + 1;
    }    
    return low;  //返回low而不是mid
}

3、一般的套路是:固定一个端点(该端点顺序遍历),而对另一个端点采用二分法搜索。

4、使用二分法,搜索空间应该是有序的。

 

 

 

two points

1、使用2个指针,或者一头一尾,或两个都从头开始扫描。可以降低复杂度。主要关注指针移动的条件。

 

 

 

 

排序

1、归并排序

合并函数

void merge(int num[], int low1, int high1, int low2, int high2){
    int temp[101];
    int index = 0, i = low1, j = low2;
    while(i <= high1 && j <= high2){
        if(num[i] < num[j])
            temp[index++] = num[i++];
        else
            temp[index++] = num[j++];
    }
    while(i <= high1)
        temp[index++] = num[i++];
    while(j <= high2)
        temp[index++] = num[j++];
    for(int k = 0; k < index; k++)
        num[low1 + k] = temp[k];
}

排序, 非递归写法

void mergeSort(int num[], int len){
  for(int step = 2; step <= len; step *= 2){ //初始步长为2, 逐步变为4、8、16 for(int i = 0; i < len; i += step){ //i + step为每个子区间的首部 int mid = i + step / 2 - 1; merge(num, i, mid, mid + 1, min(i + step - 1, len - 1)); } } }

递归写法

void mergeSort(int num[], int left, int right){
    if(left < right){
           int mid = (left + right) / 2;
           mergeSort(num, left, mid);
           mergeSort(num, mid + 1, right);
           merge(A, left, mid, mid + 1, right);  
       }
}

2、插入排序:将a[0]至a[i]视作有序序列,将a[i + 1]插入a[0]至a[i]中,使之有序。

void inser(int num[], int len){for(int i = 1; i < len; i++){
        int temp = num[i];
        int j = i - 1;
        while(j >= 0 && temp < num[j]){
            num[j + 1] = num[j];
            j--;
        }
        num[j + 1] = temp;
    }
}

3、对一个数列进行不同方法的排序时注意,对N个方法应使用N个拷贝数组,若对一个数组连续排序就会出错。

posted @ 2018-02-04 15:06  ZHUQW  阅读(354)  评论(0编辑  收藏  举报