二分查找

2020-06-26  本文已影响0人  foolish_hungry

思想:
在有序且不重复的数组中, 选中间的值和目标值做对比, 比中间值大就从后半部分数据查找, 比中间值小从前半部分数据查找, 直到找到和目标值相等的中间值, 返回其下标;

代码实现

// 循环实现
int binarySearch(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    int mid = high / 2;
    while (low <= high) {
        if (a[mid] == target) {
            return mid;
        } else if (a[mid] > target) {
            high = mid - 1;
            mid = high / 2;
        } else {
            low = mid + 1;
            mid = low + ((high - mid) >> 1);
        }
    }
    return -1;
}

// 递归实现
int binarySearch1(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    return binarySearch_recursive(a, low, high, target);
}

int binarySearch_recursive(int a[], int low, int high, int target) {
    // 递归终止条件
    while (low > high) {
        return -1;
    }
    int mid = low + ((high - low) >> 1);
    if (a[mid] == target) {
        return mid;
    } else if (a[mid] > target) {
        high = mid - 1;
        binarySearch_recursive(a, low, high, target);
    } else {
        low = mid + 1;
        binarySearch_recursive(a, low, high, target);
    }
    return -1;
}

使用

int a[] = {1, 2, 3, 4, 5, 6, 7 ,8};
    int num = sizeof(a) / sizeof(int);
    int index = binarySearch1(a, num, 4);
    printf("%d", index);

四个变体

// 变体一:查找第一个值等于给定值的元素
int binarySearch2(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    while (low <= high) {
        int mid = low + ((high - low) >> 1);
        if (a[mid] == target) {
            if (low == 0 || a[mid - 1] != target) {
                return mid;
            } else {
                high = mid - 1;
            }
        } else if (a[mid] > target) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

// 变体二:查找最后一个值等于给定值的元素
int binarySearch3(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    while (low <= high) {
        int mid = low + ((high - low) >> 1);
        if (a[mid] == target) {
            if (mid == n - 1 || a[mid + 1] != target) {
                return mid;
            } else {
                low = mid + 1;
            }
        } else if (a[mid] > target) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

// 变体三:查找第一个大于等于给定值的元素
int binarySearch4(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    while (low <= high) {
        int mid = low + ((high - low) >> 1);
        if (a[mid] >= target) {
            if (mid == 0 || a[mid - 1] < target) {
                return mid;
            } else {
                high = mid - 1;
            }
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

// 变体四:查找最后一个小于等于给定值的元素
int binarySearch5(int a[], int n, int target) {
    int low = 0;
    int high = n - 1;
    while (low <= high) {
        int mid = low + ((high - low) >> 1);
        if (a[mid] <= target) {
            if (mid == n - 1 || a[mid + 1] > target) {
                return mid;
            } else {
                low = mid + 1;
            }
        } else {
            high = mid - 1;
        }
    }
    return -1;
}
上一篇下一篇

猜你喜欢

热点阅读