C/C++_五大常規算法_分治算法

分治法

一個裝有 16 枚硬幣的袋子,16 枚硬幣中有一個是僞造的,僞造的硬幣和普通硬幣從表面上看不出有任何差別,但是那 個僞造的硬幣比真的硬幣要輕。現有給你一臺天平,請你在儘可能最短的時間內找出那枚僞造的硬幣。

常規思維:

每次從待比較的硬幣中取兩枚進行計較,如果天平平衡(相等)就繼續取剩下的硬幣進行比較
在這裏插入圖片描述
繼續以上過程,直到找到硬幣。
在這裏插入圖片描述
強者思維:
我們先將 16 枚硬幣分爲左右兩個部分,各爲 8 個硬幣,分別稱重,必然會有一半輕一半重,而我們要的就是輕的那組,重 的捨去。接下來我們繼續對輕的進行五五分,直至每組剩下一枚或者兩枚硬幣,這時我們的問題自然就解決了,下面用一 張圖進行更好的理解。
第一次檢測:
在這裏插入圖片描述
第二次檢測:
在這裏插入圖片描述
第三次檢測:
在這裏插入圖片描述
第四次檢測:
在這裏插入圖片描述
分治法——見名思義,即分而治之,從而得到我們想要的最終結果。分治法的思想是將一個規模爲 N 的問題分解爲 k 個較 小的子問題,這些子問題遵循的處理方式就是互相獨立且與原問題相同。

兩部分組成

分(divide):遞歸解決較小的問題
治(conquer):然後從子問題的解構建原問題的解

三個步驟

1、分解(Divide):將原問題分解爲若干個規模較小,相互獨立,與原問題形式相同的子問題;

2、解決(Conquer):若子問題規模較小而容易被解決則直接解決,否則遞歸地解各個子問題;

3、合併(Combine):將各個子問題的解合併爲原問題的解。

參考:

#include <stdlib.h>
#include <stdio.h>

/*************************************
* 遞歸實現二分查找
* 參數:
* arr    - 有序數組地址arr
* minSub - 查找範圍的最小下表minSub
* maxSub - 查找範圍的最大下表maxSub
* num    - 查找的數字
*
* 返回: 找到則返回所在的數組下標, 找不到則返回 -1
* 
*************************************/
int BinarySearch(int *arr,int minSub,int maxSub,int num)
{
	if (minSub > maxSub)
	{
		return -1; /* 找不到num時直接返回 */
	}

	int mid = (minSub + maxSub) / 2;

	if (num < arr[mid])
	{
		return BinarySearch(arr, minSub, mid - 1, num);
	}
	else if (num > arr[mid])
	{
		return BinarySearch(arr, mid + 1, maxSub, num);
	}
	else if(num == arr[mid])
	{
		return mid;
	}
}

int main()
{
	int arr[] = { 5,7,11,15,19,21,25,26,28,61,99 };

	int index = BinarySearch(arr, 0, 10, 26);
	printf("26在數組下標:%d\n", index);

	system("pause");
	return 0;
}

這裏畫圖理解一下
在這裏插入圖片描述
假設查找: 18

運行環境: vs2019
運行結果:
在這裏插入圖片描述

結語:

學到的知識要, 多複習, 多總結, 多敲. 需要時間的積累, 才能引起質的改變. 自己寫不出來的永遠是別人的.

分享一下我的技巧: 代數法把具體的數字帶進去, 看看能能能找到規律(掌握思想).
還有就是畫圖, 也很重要. 用筆畫出來, 把數代進去, 方法雖然笨, 但真的很實用, 好記憶不如爛筆頭!!!

我是小白, C/C++功力…, 你懂得, 寫的文章可能不是很好. 如果存在問題, 歡迎大神給予評判指正.
錯了不可怕, 可怕的是找不出bug, 誰沒錯過!!!

最近學操作系統我認爲, 學什麼都要成本(時間), 即使它是免費的, 我個人認爲要挑來學, 挑重點來學, 而不是從頭到尾, 除非考試考研.

今日是: 2020年5月9日, (由於疫情的原因)在家裏整天坐在電腦前, 眼神逐漸從大到小, 視力也有所大大的下降 ,中午期待打籃球. 寫博客,也可自己加強記憶,就當寫寫日記吧!!!

希望給個贊: 反正你又不虧, 順便而已

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章