二分查找的實現及解析

二分查找:

//2018年4月21日  

#include<stdio.h>

int search_value(int *ar,int n,int x);//(二分查找法)
int search_value_digui(const int *ar,int left,int right, int x);
int main()
{

	int a[10] = {13,24,34,41,49,67,71,72,86,87,};
	int n = sizeof(a)/sizeof(a[0]);

	printf("%d\n",search_value(a,n,67));
	printf("%d\n",search_value_digui(a,0,n-1,67));
	return 0;
}
int search_value(int *ar,int n,int x)
{
	//二分查找法的前提是數據是有序的
	//一定記住函數參數的判斷;ar要判空,n,x也要判斷其範圍
	int i = 0;
	int j = n-1;
	int pos = -1;
	int mid = 0;
	while(i<=j)
	{
		mid = (i+j)/2;//i+j也要考慮溢出的問題
		              ///int mid = (j - i + 1)/2 +i;(j-i)不會出現溢出問題
		//? 如果要找到靠最左邊的數字(2)呢?如何編寫程序?(考慮重複值)
		 // a[] = {1,2,2,2,2,3,4,5,6,};
		if(x == ar[mid])
		{
			while(mid>i && ar[mid-1] == x)
				mid--;//(考慮重複值,返回最左邊元素下標)
			pos = mid;
			break;
		}
		if(x > ar[mid])
		{
			i = mid + 1;
		}
		else
		{
			j = mid - 1;
		}
	}
		return pos;
}


//以上的二分查找能否改成遞歸呢?
int search_value_digui(const int *ar,int left,int right, int x)
{
	int pos = -1;
	if(ar == NULL || right<1) //首先一定要判空及判斷參數範圍
		return -1;
	if(left <=right )
	{
		int mid = (right - left +1)/2 + left;
		if(ar[mid] == x)
		{
			while(mid>left && ar[mid-1] == x)
				--mid;
			pos = mid;
		}else if(x < ar[mid])
		{
			pos = search_value_digui(ar,left,mid-1,x);
		}else
		{
			pos = search_value_digui(ar,mid+1,right,x);
		}
	}

		return pos;
	
}

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