折半查找算法、二分查找算法

找出给定的有序数列中是否含有某个数,如果有,则给出下标。
自己构想的查找办法居然与折半查找算法(二分查找算法)一毛一样

#include <stdio.h>
int main()
{
	int arr[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};//原始数列
	int k = 0;//要寻找的数
	int ch = 0;//用于清空输入缓冲区
	int sz = sizeof(arr)/sizeof(arr[0]);//计算数列大小
	int zj = 0;//用于判断数列递增/递减的变量
	int i =0;//循环变量
	int ksetl=0;//左边界
	int ksetr=sz-1;//右边界
	int kset=0;//插入点,一般为数列的中点
	if (arr[sz-1] > arr[0])
	//通过数列第0位和最后1位比较大小,判断数列的增减性
	    zj = 1;
	else 
		zj = -1;
again:
	 i =0;//重置循环变量
	ksetl=0;//重置左边界
	ksetr=sz-1;//重置右边界
	kset=0;//重置插入点,一般为数列的中点
	ch = 0;
	printf("输入要查找的数:>");
	scanf("%d",&k);//将输入值赋值给K
	while((ch = getchar())!= '\n' && ch != EOF)//清空输入缓冲区
	{	;	}//空语句,while(){}语句的标准结构,配合完成清空输入缓冲区
	switch (zj)
	{
	case 1://递增数列
		kset = sz/2;//插入点在数列中间
		for (i = 0; i < sz/2; i++)
		{
			if (k > arr[kset] && k <= arr[ksetr])
			//如果给定的数k大于插入点
			{
				ksetl = kset+1;
				//把插入点的下一位定位为新区间的左边界
				kset = (ksetl + ksetr)/2;
				//将新区间的中点定位新插入点
			}
			else if (k < arr[kset] && k >= arr[0])
			//如果给定的数k小于插入点
			{
				ksetr = kset-1;
				//将插入点的前一位定为新区间的右边界
				kset = (ksetl+ksetr)/2;
				//将新区间的中点定位新插入点
			}
			else if ( k == arr[kset])
			//如果给定的数K等于插入点的数
			{
				printf("找到了,下标为【%d】\n",kset);
				break;//找到后即可跳出for循环
			}
			else 
			//不满足大于、小于、等于的所有判断
			//则说明给定的数不在数列中
			{
				printf("\n没有这个数\n\n");
			    break;//没有这个数,将跳出for循环
		    }
		}
		break;//跳出switch-case循环
	case -1://递减数列,逻辑过程同上
		kset = sz/2;
		for (i = 0; i < sz/2; i++)
		{
			if (k > arr[kset] && k <= arr[0])
			{
				ksetr = kset-1;
				kset = (ksetl + ksetr)/2;
			}
			else if (k < arr[kset] && k >=arr[ksetr] )
			{
				ksetl = kset+1;
				kset = (ksetl + ksetr)/2;
			}
			else if ( k == arr[kset])
			{
				printf("找到了,下标为%d\n",kset);
				break;
			}
			else 
			{
				printf("没有这个数\n");
				break;
			}
		}
		break;
	default:
		break;
	}
	goto again;
	return 0;
}

用函数实现

//在有序数列v[n-1]中,查找x
#include <stdio.h>
#include <math.h>
int binsearch(int x, int v[], int n )
//定义二分查找函数,参数包括要查找的数X,所在数组V,数组元素个数n
{
	int lft = 0;
	int rit = n-1 ;
	int mid = (lft+rit)/2;
	int i = (int)(log(rit)/log(2));
	int j = 0;
	if (x>= v[0] && x<= v[rit])
	{
		for (j = 0; j <= i+2; j++)
		{
			if (x > v[mid] && x <= v[rit])
			{
				lft = mid+1;
				mid = (lft +rit)/2;
			}
			else if (x >= v[0] && x < v[mid])
			{
				rit =mid -1;
				mid = (lft +rit)/2;
			}
			else if (x == v[mid])
			{
				printf("一共经过%d步,找到该数,下标为【%d】。\n", j+1, mid);
				break;
			}
			else
			{
				printf("查无此数\n");
				break;
			}
	    }
	}
	else
		printf("查无此数\n");
	
	return 0;

}

int main()
{
	int v[]= {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23};
	int sz =  sizeof(v)/sizeof(v[0]);
	binsearch(23, v, sz);
	getch();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值