二分法(分而治之核心思想)

"分而治之"(Divide and Conquer)是一种算法设计策略,它将一个问题分解成更小的、相互独立的子问题,然后递归地解决这些子问题,最后将它们的解合并起来,得到原始问题的解。这个策略通常包含三个步骤:

  • 分解(Divide): 将原问题分解为若干个规模较小的子问题。这一步通常通过递归的方式来实现。

  • 解决(Conquer): 递归地解决这些子问题。如果子问题足够小,就直接解决。

  • 合并(Combine): 将子问题的解合并成原问题的解。

这个思想常常用于解决一些复杂的问题,例如排序、查找、图算法等。一些著名的算法,比如归并排序和快速排序,就是分而治之的典型例子。

下面以归并排序为例来说明分而治之思想的应用:

归并排序的步骤

  • 分解: 将待排序的数组分成两半。

  • 解决: 递归地对这两半数组进行归并排序。

  • 合并: 将两个已排序的子数组合并成一个有序的数组。

这个过程一直递归下去,直到子问题的规模足够小,可以直接解决。通过这样的分治策略,最终整个数组被排序。

分而治之的优点

  • 简化复杂问题: 将一个大问题分解为若干个小问题,使问题的解决变得更加简单和直观。

  • 提高效率: 在某些情况下,分而治之可以通过并行处理来提高算法的效率。

  • 可复用性: 将问题分解为独立的子问题,这些子问题可以在不同的上下文中被复用。

  • 可维护性: 代码结构清晰,易于理解和维护。

总体来说,分而治之是一种强大的问题解决思想,能够在设计算法时提供清晰的思路和结构。

二分法查找实例

#include <stdio.h>
//1.正常数组的查找
int searchData(int array[], int arrayNum, int posData) 
{
	for (int i = 0; i < arrayNum; i++) 
	{
		if (array[i] == posData)
			return i;
	}
	return -1;
}
//2.正常的二分查找--->有序的
int binarySerachData(int array[], int arrayNum, int posData)
{
	int left = 0;
	int right = arrayNum - 1;			//右边的数组下标是等于数组长度-1
	while (left <= right) 
	{
		int mid = (left + right) / 2;
		if (array[mid] == posData) 
		{
			return mid;
		}
		else if (array[mid] > posData) 
		{
			right = mid - 1;
		}
		else 
		{
			left = mid + 1;
		}
	}
	return -1;
}
//3.分而治之的二分查找
int binarySearch(int array[], int left, int right, int posData)
{
	if (left > right)
		return -1;
	int mid = (left + right) / 2;
	if (array[mid] == posData)
		return mid;
	else if (array[mid] > posData)	//左边的问题
	{
		return binarySearch(array, left, mid - 1, posData);
	}
	else                              
	{
			//右边问题
		return binarySearch(array, mid+1, right, posData);
	}

}
int main() 
{
	int array[10] = { 0,1,2,3,4,5,6,7,8,9 };
	printf("index:%d\n", binarySerachData(array, 10, 1));
	printf("index:%d\n", binarySearch(array, 0,9, 1));
	return 0;
}

双重找最值实例

#include <stdio.h>
/*
	1.找最大值和最小值
*/
//正常写法
void searchMaxMin(int array[], int arrayNum, int* maxIndex, int* minIndex) 
{
	int max = array[0];
	int min = array[0];
	*maxIndex = 0;
	*minIndex = 0;
	for (int i = 1; i < arrayNum; i++)
	{
		if (array[i] > max)
		{
			max = array[i];
			*maxIndex = i;
		}
		if (array[i] < min) 
		{
			min = array[i];
			*minIndex = i;
		}
	}
}
void searchMaxMin2(int array[], int arrayNum, int* maxIndex, int* minIndex) 
{
	//1.只有一个元素
	if (arrayNum == 1) 
	{
		*maxIndex = *minIndex = 0;
	}
	//2.先解决奇偶问题
	int n = 1;
	if (arrayNum % 2 == 1) 
	{
		*maxIndex = *minIndex = 0;
	}
	else 
	{
		if (array[0] > array[1]) 
		{
			*maxIndex = 0;
			*minIndex = 1;
		}
		else 
		{
			*maxIndex = 1;
			*minIndex = 0;
		}
		n = 2;
	}
	for (int i = n; i < arrayNum; i += 2) 
	{
		if (array[i] > array[i + 1])	//下一组找出最小和最大的
		{
			if (array[i] > array[*maxIndex])  //大的跟大的比
			{
				*maxIndex = i;
			}
			if (array[i + 1] < array[*minIndex])	//小的跟小的比 
			{
				*minIndex = i + 1;
			}
		}
		else 
		{
			if (array[i + 1] > array[*maxIndex]) 
			{
				*maxIndex = i + 1;
			}
			if (array[i] < array[*minIndex]) 
			{
				*minIndex = i;
			}
		}
	}
}
int main() 
{
	int array[10] = { 4,5,7,8,9,0,1,6,2,3 };
	int maxIndex = -1;
	int minIndex = -1;
	searchMaxMin(array, 10, &maxIndex, &minIndex);
	printf("max=%d\nmin=%d\n", maxIndex, minIndex);
	maxIndex = -1;
	minIndex = -1;
	searchMaxMin2(array, 10, &maxIndex, &minIndex);
	printf("max=%d\nmin=%d\n", maxIndex, minIndex);
	return 0;
}

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值