[Estructura de datos y algoritmo] Depósito de familia de búsqueda binaria C ++

0, Leetcode 704 búsqueda binaria

Dado un n-elemento ordenado (ascendente) de matriz de números enteros y un objetivo de valor objetivo, escriba una función para buscar el objetivo en números y devuelva el subíndice si el valor objetivo existe; de ​​lo contrario, devuelva -1.

class Solution {
    
    
public:
    int search(vector<int>& nums, int target) {
    
    
        int left = 0, right = nums.size()-1;// 在【left,right】范围里寻找target
        while(left <= right){
    
     // 当left == right时,区间【left,right】仍然有效,该继续查找,所以是left <= right
            int mid = left + (right-left)/2;
            if(nums[mid] == target){
    
    
                return mid;
            }
            if(target > nums[mid]){
    
    
                left = mid + 1;//target在【mid+1, right】中
            }else{
    
    
                right = mid - 1;//target在【left, mid+1】中
            }
        }
        return -1; // 没有找到
    }
};

Aclare el significado de las variables, mantenga invariantes de bucle, depure con pequeñas cantidades de datos y pruebe con grandes cantidades de datos.
El código anterior busca el objetivo en [izquierda, derecha] y el siguiente código busca el objetivo en [izquierda, derecha).

class Solution {
    
    
public:
    int search(vector<int>& nums, int target) {
    
    
        int left = 0, right = nums.size();// 在【left,right)范围里寻找target
        while(left < right){
    
     // 当left == right时,区间【left,right)无效,不该继续查找,所以是left < right
            int mid = left + (right-left)/2;
            if(nums[mid] == target){
    
    
                return mid;
            }
            if(target > nums[mid]){
    
    
                left = mid + 1;//target在【mid+1, right)中
            }else{
    
    
                right = mid;//target在【left, mid)中
            }
        }
        return -1; // 没有找到
    }
};

1. La implementación clásica de la búsqueda binaria

/*************************最基本的二分查找*********************************/

int BinarySearchUp(int * nums,int numslen,int key){
    
    //针对升序数组,非递归实现
	int high, low, mid;
	high = numslen - 1;
	low = 0;
	while (low <= high){
    
    
		mid = high - (high - low) / 2;//更新mid的位置
		if (key == nums[mid]){
    
    //找到了
			return mid;
		}
		else if (key < nums[mid]){
    
    //key在左半边
			high = mid - 1;
		}
		else{
    
    //key在右半边
			low = mid + 1;
		}
	}
	return -1;
}

int BinarySearchDown(int * nums, int numslen, int key){
    
    //针对降序数组,非递归实现
	int high, low, mid;
	high = numslen - 1;
	low = 0;
	while (low <= high){
    
    
		mid = high - (high - low) / 2;//更新mid的位置
		if (key == nums[mid]){
    
    //找到了
			return mid;
		}
		else if (key < nums[mid]){
    
    //key在右半边
			low = mid + 1;
		}
		else{
    
    //key在左半边
			high = mid - 1; 
		}
	}
	return -1;
}

int BinarySearchUpRecursive(int * nums, int low, int high, int key){
    
    //针对升序数组,采用递归实现
	//边界条件判断
	if (low > high){
    
    
		return -1;
	}

	int mid = low + (high - low) / 2;//计算mid的位置
	if (key == nums[mid]){
    
    //找到了
		return mid;
	}
	else if (key > nums[mid]){
    
    //key在右半边
		return BinarySearchUpRecursive(nums, mid + 1, high, key);
	}
	else{
    
    //key在左半边
		return BinarySearchUpRecursive(nums, low, mid - 1, key);
	}
}

2. Cuando la matriz contiene elementos repetidos, encuentre los límites izquierdo y derecho de los elementos repetidos

2-1. Encontrar el límite izquierdo del área de valor objetivo = encontrar la posición del primer elemento igual al valor objetivo = encontrar la posición del primer elemento no menor que el valor objetivo

/*************************查找目标值区域的左边界*******************************************/
/*************************查找与目标值相等的第一个元素位置*********************************/
/*************************查找第一个不小于目标值的元素位置*********************************/

int BinarySearchLowerBound(int * nums, int numslen, int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key <= nums[mid]){
    
    //不在右半边
			high = mid - 1;
		}
		else{
    
    //在右半边
			low = mid + 1;
		}
	}
	if (nums[low] == key){
    
    //low < numslen && 
		return low;
	}
	else{
    
    
		return -1;
	}
}

2-2. Encontrar el límite correcto del área de valor objetivo = Encontrar la posición del último elemento igual al valor objetivo = Encontrar la posición del primer elemento no mayor que el valor objetivo

/*************************查找目标值区域的右边界*******************************************/
/*************************查找与目标值相等的最后一个元素位置*********************************/
/*************************查找第一个不大于目标值的元素位置*********************************/

int BinarySearchUpperBound(int * nums,int numslen, int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key >= nums[mid]){
    
    //不在左侧
			low = mid + 1;
		}
		else{
    
    //在左侧
			high = mid - 1;
		}
	}
	if (key == nums[high]){
    
     //high >= 0 &&
		return high;
	}
	else{
    
    
		return -1;
	}
}

2-3. Encontrar el primer número mayor que el valor objetivo = Encontrar el número mayor que el valor objetivo pero más cercano al valor objetivo

/*************************查找第一个大于目标值的数*******************************************/
/*************************查找比目标值大但是最接近目标值的数*********************************/
/*
我们已经找到了最后一个不大于目标值的数,那么再往后进一位,
返回high + 1,就是第一个大于目标值的数。*/
int BinarySearchBiggerOne(int * nums,int numslen,int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key >= nums[mid]){
    
    //不在左边
			low = mid + 1;
		}
		else{
    
    
			high = mid - 1;
		}
	}
	if (high+1 < numslen && key == nums[high]){
    
    
		return high + 1;
	}
	else{
    
    
		return -1;
	}
}

2-4. Encontrar el último número menor que el valor objetivo = Encontrar el número menor que el valor objetivo pero más cercano al valor objetivo

/*************************查找最后一个小于目标值的数*******************************************/
/*************************查找比目标值小但是最接近目标值的数*********************************/
int BinarySearchLessOne(int * nums, int numslen, int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key <= nums[mid]){
    
    //不在右边
			high = mid - 1;
		}
		else{
    
    //在右边
			low = mid + 1;
		}
	}
	if (low - 1 >= 0 && key == nums[low]){
    
    
		return low - 1;
	}
	else{
    
    
		return -1;
	}
}

3. Problema de matriz giratoria

3-1. Encuentre el subíndice de elemento mínimo de la matriz rotada (asumiendo que no hay números repetidos)

/*************************查找旋转数组的最小值元素下标(假设不存在重复数字)*********************************/
int BinarySearchRotateMinUnique(int * nums, int numslen){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low < high){
    
    
		mid = low + (high - low) / 2;
		if (nums[mid] > nums[high]){
    
    //说明最小值在右半边
			low = mid + 1;
		}
		else{
    
    //说明最小值不在右半边
			high = mid;
		}
	}
	return high;//此时low=high,写return high;一样的
}

3-2, encuentre el subíndice de elemento mínimo de la matriz rotada (asumiendo que hay números duplicados)

/*************************查找旋转数组的最小值元素下标(假设存在重复数字)*********************************/
int BinarySearchRotateMinRepeated(int * nums, int numslen){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low < high){
    
    
		mid = low + (high - low) / 2;
		if (nums[mid] > nums[high]){
    
    //最小值在右半边
			low = mid + 1;
		}
		else if (nums[mid] < nums[high]){
    
    //最小值不在右半边
			high = mid;
		}
		else{
    
    //最小值可能为当前值,也可能在左半边,也可能在右半边
			high--;//小步前进
		}
	}
	return low;
}

3-3. Buscar en la matriz ordenada giratoria (suponiendo que no haya números duplicados)

/*************************在旋转排序数组中搜索(假设不存在重复数字)*********************************/
int BinarySearchKeyInRotateUnique(int * nums, int numslen, int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key == nums[mid]){
    
    
			return mid;
		}
		else if (nums[low] <= nums[mid]){
    
    //左半边是有序的
			if (key >= nums[low] && key < nums[mid]){
    
    //key在左半边
				high = mid - 1;
			}
			else{
    
    //key在右半边
				low = mid + 1;
			}
		}
		else if (nums[mid] <= nums[high]){
    
    //右半边是有序的
			if (key>nums[mid] && key <= nums[high]){
    
    //key在右半边
				low = mid + 1;
			}
			else{
    
    //key在左半边
				high = mid - 1;
			}
		}
	}
	return -1;
}

3-4. Buscar en la matriz ordenada giratoria (asumiendo que hay números duplicados)

/*************************在旋转排序数组中搜索(假设存在重复数字)*********************************/
bool BinarySearchKeyInRotateRepeat(int * nums, int numslen, int key){
    
    
	int low = 0, high = numslen - 1, mid;
	while (low <= high){
    
    
		mid = low + (high - low) / 2;
		if (key == nums[mid]){
    
    
			return true;
		}
		else if (nums[low] < nums[mid]){
    
    //左半边有序
			if (key >= nums[low] && key < nums[mid]){
    
    //key在左半边
				high = mid;
			}
			else{
    
    //key在右半边
				low = mid + 1;
			}
		}
		else if (nums[mid] < nums[high]){
    
    //右半边有序
			if (key > nums[mid] && key <= nums[high]){
    
    //key在右半边
				low = mid + 1;
			}
			else{
    
    //key在左半边
				high = mid;
			}
		}
		else {
    
    
			high--;
		}
	}
	return false;
}

4. Pruebe la función anterior

#include<iostream>
using namespace std;

假装这里有上述的所有函数

int main(){
    
    
	int data[] = {
    
     6, 5, 4, 3, 2, 1 };
	int data2[] = {
    
     1, 2, 3, 4, 5, 6 };
	int data3[] = {
    
     1, 3, 7, 7, 7, 14, 14, 14 };
	int data4[] = {
    
     4, 5, 6, 7, 8, 1, 2, 3 };
	int data5[] = {
    
     5, 5, 5, 6, 7,7,7, 8,8, 2, 2, 2, 3 };

	这里调用函数即可
	bool num = BinarySearchKeyInRotateRepeat(data5, 13, 2);//此种情况显示的是有或无
	
	cout << "Index of the number is " << num <<"."<<endl;
	system("pause");
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_30885821/article/details/108228900
Recomendado
Clasificación