【算法设计】递归与分治算法设计——二分搜索、假币识别问题(C++实现)

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡><)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
更多算法分析与设计知识专栏:算法分析
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ


目录

  • 一、二分搜索问题
    • 问题描述
    • 算法思想和解题思路
    • C++代码
  • 二、假币识别问题
    • 问题描述
    • 算法思想和解题思路
    • C++代码

一、二分搜索问题

二分搜索解题框架见:【算法】分治法的基本思想和二分搜索的应用

问题描述

a[0:n-1]是已排好序的数组

试改写二分搜索算法,使得当搜索元素x不在数组a中时,返回小于的最大元素的位置i大于x的最小元素的位置j

当搜索元素x在数组a中时,返回x在数组中的位置,此时i和j相同

算法思想和解题思路

先将有序数组分成两部分,中间位置mid为基准值

  • 若该值等于目标值key,则直接返回

  • 若该值大于目标值,则在左半部分进行二分搜索

  • 若该值小于目标值,则在右半部分进行二分搜索

循环执行二分搜索,直到左侧low标记大于右侧high标记,跳出循环则为查找失败,此时的begin就是比x大的最小数组元素下标,end就是比x小的最大元素数组下标

二分算法运作的核心理念是将数组分割为两部分,然后根据所查找或排序的元素与中间元素的比较结果,将查找或排序的范围缩小一半

C++代码

#include 
using namespace std;
/*
二分搜索问题:设a[0:n-1]是已排好序的数组。试改写二分搜索算法,
使得当搜索元素x不在数组a中时,返回小于x的最大元素的位置i和大于x的最小元素的位置j;
当搜索元素x在数组a中时,返回x在数组中的位置,此时i和j相同。
*/
void binarySearch(int arr[],int target)
{
	int length = 7;
	int left = 0;
	int right = length - 1;
	if (target < arr[0]) {
		cout << "比x大的最小数组元素的下标是0" << endl;
		cout << "不存在比x小的数组元素" << endl;
		return;
	}
	else if (target > arr[length - 1]) {
		cout << "不存在比x大的数组元素" << endl;
		cout << "比x小的最大数组元素的下标是" << right << endl;
		return;
	}
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] == target) {
			cout << "与x相等的数据元素的下标是" << mid << endl;
			return;
		}
		else if (arr[mid] < target) {
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}
	cout << "比x大的最小数组元素的下标是" << left << endl;
	cout << "比x小的最大数组元素的下标是" << right << endl;
	return ;
}

int main()
{
	int a[] = { 2,3,4,5,6,8,9 };
	binarySearch(a, 7);
	binarySearch(a, 4);

	return 0;
}

【算法设计】递归与分治算法设计——二分搜索、假币识别问题(C++实现)_第1张图片

二、假币识别问题

问题描述

一个袋子里有n个硬币,其中一枚是假币,假币和真币外观一模一样,仅凭肉眼无法区分,但是已知假币比真币轻一些

试设计识别假币的分治算法

算法思想和解题思路

先判断当前硬币数量是奇数还是偶数

  • 如果硬币数量是偶数,那么我们需要做的是检查这些硬币是否只有两枚。如果是,那么比较这两枚硬币的重量,较轻的那枚就是假币。如果没有只有两枚硬币,那么我们将这些硬币分成两堆,比较这两堆的重量,轻的那堆中会有假币。

  • 如果硬币数量是奇数,我们需要做的是取出中间的那枚硬币。然后,将剩余的硬币分成两部分。如果这两部分的重量相等,那么假币就是我们之前取出的中间那枚。如果这两部分的重量不相等,就重复到只有两个硬币比较重量,轻的一个就是假币

分治法将一个问题分解为多个子问题,并递归地解决这些子问题,最后将子问题的解合并为原问题的解

C++代码

#include   
using namespace std;

// 判断硬币是否为假币  
bool isfake(int coin[], int n, int i) {
    for (int j = 0; j < i; j++) {
        if (coin[j] < coin[i]) {
            return true;
        }
    }
    for (int j = i + 1; j < n; j++) {
        if (coin[j] < coin[i]) {
            return true;
        }
    }
    return false;
}
// 识别假币的分治算法  
void search(int coin[], int n) {
    if (n == 2) {
        // 当硬币数量为2时,输出重量较轻的硬币  
        if (coin[0] < coin[1]) {
            cout << coin[0] << endl;
        }
        else {
            cout << coin[1] << endl;
        }
    }
    else if (n % 2 == 0) {
        // 当硬币数量为偶数时,将硬币分成两段,并比较两段的平均重量  
        int mid = n / 2;
        if (isfake(coin, n, mid)) {
            search(coin, mid);
        }
        else {
            search(coin + mid, n - mid);
        }
    }
    else {
        // 当硬币数量为奇数时,去掉中间的硬币,将剩余的硬币分成两段,并比较两段的平均重量  
        int mid = (n - 1) / 2;
        if (isfake(coin, n, mid + 1)) {
            search(coin, mid + 1);
        }
        else {
            search(coin + mid + 1, n - mid - 1);
        }
    }
}

int main() {
    int arr[4] = { 2,4,2,5 };
    search(arr, 4);
    return 0;
}

【算法设计】递归与分治算法设计——二分搜索、假币识别问题(C++实现)_第2张图片


大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)

你可能感兴趣的:(算法分析,算法,c++,开发语言,学习,笔记)