1. 程式人生 > >二分查找個人理解分析

二分查找個人理解分析

二分演算法理解
二分是一種我們十分熟知的演算法,在很多的地方都有著神奇的用處,在各大比賽上都是很有用的工具性演算法

我們可以把二分理解成是一種不斷縮小答案範圍最後找到解的演算法,但是需要注意的是,他的實現是在資料有序的基礎上實現的
假設我們現在有著這樣一組資料
10
1 2 3 4 5 6 7 8 9 10
要尋找 3 的位置
二分法的思路便是這樣的:
①取出最中間的數即是 5 ,以及定址空間 1~10
3 比 5 小,所以是在 5 的左邊的,由此定址空間便變化為 1~4
②取出中間的數 2 (定址空間 1~4 )
3 比 2 大 ,所以是在 2 的右邊,由此定址空間變化為 3~4;
③取出中間數 3 (定址空間 3~4)
3 == 3 ,找到解了
PS:我們的範圍是上一次中間數向前減 1 ,或向前加 1 的,這樣不會重複,避免取出錯誤的中間數

這是很容易去理解的,程式碼也很容易去記住以及理解,但是二分答案的難點是在對答案是否合法,以及邊界的判斷上,我們很需要注意的

二分演算法實現
非遞迴法
這種方法是以while迴圈來實現的

程式碼:

int main()
{
	///輸入

	//sort(a+1,a+n+1);    注意,一定是要有序的!!!
	
	left = 1;             //取最小的,即是第一個(常理下都是升序的)
	right = n;            //最大的

	while (left <= right)                    //判斷是否還有定址空間
		{
			mid = (left + right) / 2;         //去中間數的下標
			
			if (a[mid] == k) break;         //可以理解成邊界,也就是找到解的下標了
			//沒找到的情況
			if (a[mid] < k) right = mid + 1;    //①在答案的左邊,縮小定址空間                  
			
			if (a[mid] > k) left = mid - 1;     //②在答案的右邊,縮小定址空間
		}

	cout<<mid;      ///輸出答案的下標
}

遞迴法實現
遞迴的也是很好理解的,但是程式碼相較上面的用while來實現的要難記住一些,兩種方法是個有千秋的,在不同的題型上,不同的方式有不同的優點,這是需要我們來分析的,也是在做題的過程中需要注意的

程式碼:

int get(int left,int key,int right)     //幾個形參,left是左邊到哪兒,key是要查詢的關鍵字,right是右邊到哪兒
{	
	int mid = (left + right) / 2;            //取中間數的下標
	
	if (left > right) return -1;            //邊界①:無解
	
	if (a[mid] == key) return mid;        //邊界②:找到解
	 //下面兩個對範圍的斷定和上面while的性質一樣,只是用遞迴來實現罷了
	if (a[mid] < key) return get(mid+1,key,right);      
	
	if (a[mid] > key) return get(left,key,mid-1);
}

int main()
{
	輸入;
	
	ans = get(1,k,n);             //輸入範圍,用ans來存下標
	
	cout<<ans;
}

總結
二分是一種速度快的飛起的演算法,好了,88
二分查詢是一種很有用的工具,在很多地方能做到很大的用處,我們要加強對其的練習,在賽場上可以熟練準確的敲出來

																					** 菜雞c_uizrp_dzjopkl原創**