您的位置:首页 > 其它

二分法查找例子

2011-05-03 10:37 141 查看
#define SEARCH_NOT_FOUND -1	//没有找到查询的目标
/************************************************************************/
/* 二分法查找[递归实现版本]												*/
/*		arr:	待查找的数组											*/
/*		first:  搜索开始下标											*/
/*		last:	搜索结束下标的后一位置									*/
/*		target:	搜索的目标值			                                */
/*		pcount:	查找次数												*/
/*		返回值:	搜索到小标位置,如果没有找到则返回SEARCH_NOT_FOUND		*/
/************************************************************************/
int binarySearchWithRecursion(const int arr[],int first,int last,int target,int *pcount)
{
if (pcount)//统计查找次数
{
(*pcount)++;
}
if (first<0 || first>=last)//如果开始下标小于零或者开始下标大于或等于结束下标则说明不能找到
{
return SEARCH_NOT_FOUND;
}

int mid = (first+last)/2;
if (target==arr[mid])//找到
{
return mid;
}

if (target<arr[mid])//目标小于mid位置的值
{
return binarySearchWithRecursion(arr,first,mid,target,pcount);//搜索前子表
}

if (arr[mid]<target)//目标大于mid位置的值
{
return binarySearchWithRecursion(arr,mid+1,last,target,pcount);//搜索后子表
}

return SEARCH_NOT_FOUND;
}

/************************************************************************/
/* 二分法查找[非递归实现版本1]:                                         */
/*		parray_start:	数组开始指针									*/
/*		parray_end:		数组尾部指针									*/
/*		target:			待查找的的目标参数								*/
/*		pcount:			返回查找的次数									*/
/*		返回值:			找到的数的指针,没有找到返回空指针
/************************************************************************/
const int * binarySearchWithNoRecursion1(const int * parray_start,const int * parray_end,int target,int *pcount)
{
//如果开始指针为空或者结束指针为空或者开始指针大于等于结束指针则返回
if (!parray_start || !parray_end || parray_start>=parray_end)
{
return NULL;
}

do
{
if (pcount)//如果计数器指针有效那么递增计数器
{
(*pcount)++;
}
const int * parray_mid = parray_start+(parray_end - parray_start)/2;//取得中间指针
if (*parray_mid==target)//如果中间指针的值等于目标值则找到,立即返回该中间指针
{
return parray_mid;
}
if (target<*parray_mid)//如果目标值小于中间指针值则修改子表末尾指针为中间指针[查询前半段]
{
parray_end = parray_mid;
continue;
}
if (*parray_mid<target)//如果目标值大于中间指针则修改子表开始之真能为中间指针加一
{
parray_start = parray_mid+1;
continue;
}
} while (parray_start<parray_end);//如果开始指针仍然还小于结束指针则继续下一轮循环

return NULL;//没有找到这个数返回空指针
}

/************************************************************************/
/* 二分法查找[非递归实现版本2]:                                         */
/*		parray:	数组指针												*/
/*		len:	数组长度												*/
/*		target:	待查找的的目标参数										*/
/*		pcount:	返回查找的次数											*/
/*		返回值:	找到的数的指针,没有找到返回空指针
/************************************************************************/
const int * binarySearchWithNoRecursion2(const int * parray,const int len,int target,int *pcount)
{
if (!parray || len==0)//如果数组指针为空或者数组长度等于零则返回空
{
return NULL;
}

int first = 0;	//开始下标
int last = len;	//结束下标
int mid = 0;

while (first<last)
{
if (pcount)
{
(*pcount)++;
}
mid = (first+last)/2;
if (target==*(parray+mid))//如果目标数等于中间指针值则返回中间指针
{
return parray+mid;
}
if (target<*(parray+mid))//如果目标数小于中间指针值则修改结束下标为中间下标
{
last = mid;
continue;
}
if (*(parray+mid)<target)//如果目标数大于中间指针则修改开始下标为中间下标+1
{
first=mid+1;
continue;
}
}
return NULL;
}


测试:

/////////////////////////////////////////////////////////////////////////////
// CDlgDS2 message handlers
void CDlgDS2::OnButtonSearch()
{
// TODO: Add your control notification handler code here

int num_array[]={21,22,34,67,87,90,98,99,100};
int count = 9;//数组长度
int findCount=0;//查找次数

//使用递归版本测试
// 	int index = binarySearchWithRecursion(num_array,0,count,GetDlgItemInt(IDC_EDIT_NUM),&findCount);//查找
//
// 	char msg[32];//显示的消息
// 	char nums[3];
// 	itoa(index,nums,10);
//
// 	if (index==SEARCH_NOT_FOUND)
// 	{
// 		strcpy(msg,"没有找到这个数");
// 		SetDlgItemText(IDC_FIND_INDEX,msg);
// 	} else
//
// 	{
// 		strcpy(msg,"该数下标:");
// 		strcat(msg,nums);
// 		strcat(msg,"/n/n查找次数:");
// 		memset(nums,0,3);
// 		itoa(findCount,nums,10);
// 		strcat(msg,nums);
// 		SetDlgItemText(IDC_FIND_INDEX,msg);
// 	}

//使用非递归版本测试1
// 	const int * parraryIndex = binarySearchWithNoRecursion1(num_array,num_array+count,GetDlgItemInt(IDC_EDIT_NUM),&findCount);//查找
// 	char msg[32];//显示的消息
// 	char nums[3];
// 	itoa(parraryIndex-num_array,nums,10);//parraryIndex-num_array==查找目标在数组中的下标
//
// 	if (parraryIndex==NULL)
// 	{
// 	 		strcpy(msg,"没有找到这个数");
// 	 		SetDlgItemText(IDC_FIND_INDEX,msg);
// 	}
// 	else
// 	{
// 		 strcpy(msg,"该数下标:");
// 		 strcat(msg,nums);
// 		 strcat(msg,"/n/n查找次数:");
// 		 memset(nums,0,3);
// 		 itoa(findCount,nums,10);
// 		 strcat(msg,nums);
// 		SetDlgItemText(IDC_FIND_INDEX,msg);
// 	}

//使用非递归版本测试2
const int * parraryIndex = binarySearchWithNoRecursion2(num_array,count,GetDlgItemInt(IDC_EDIT_NUM),&findCount);//查找
char msg[32];//显示的消息
char nums[3];
itoa(parraryIndex-num_array,nums,10);//parraryIndex-num_array==查找目标在数组中的下标

if (parraryIndex==NULL)
{
strcpy(msg,"没有找到这个数");
SetDlgItemText(IDC_FIND_INDEX,msg);
}
else
{
strcpy(msg,"该数下标:");
strcat(msg,nums);
strcat(msg,"/n/n查找次数:");
memset(nums,0,3);
itoa(findCount,nums,10);
strcat(msg,nums);
SetDlgItemText(IDC_FIND_INDEX,msg);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: