二分查找(C语言)

1.定义列表结构体

typedef struct List
{
	int *data;//数组 
	int length;//总长度 
	int num;//当前长度 
}List;

 2.初始化列表

List *initList(int length)
{/*参数length:数组总长度空间*/
	List *list = (List*)malloc(sizeof(List));//申请列表的结构体空间 
	list->data = (int*)malloc(sizeof(int)*length);//申请列表结构体内的data空间 
	list->length = length;//将总长度写入列表结构体 
	list->num = 0;//当前元素个数初始为0 
	return list;//函数指针,返回一个指针 
}

 3.向列表结构体中写入元素

void listAdd(List *list,int data)
{/*参数一:列表指针
参数二:要写入的元素*/
	list->data[list->num] = data;//把当前元素的个数作为下标,将元素写入列表结构体 
	list->num += 1;//列表结构体中当前元素个数加一 
}

 4.遍历输出

void printList(List *list)
{/*参数list:列表指针*/
	int i;
	for(i=0;i<list->num;i++)//按序输出列表中的元素 
		printf("%d ",list->data[i]);
	printf("\n");
}

 5.二分查找

int binarySearch(List *list,int key)
{/*参数一:列表指针
参数二:要查找的元素*/
	int start=0,end=list->data[list->num-1];//初始时start为0,end为数组最后一个元素的下标 
	int mid;
	int i;
	while(start<=end)
	{/*如果查找元素大于中间元素,说明查找元素可能在数组后一半内,
	此时start增加为mid+1.
	如果查找元素小于中间元素,说明查找元素可能在数组的前一半内,
	此时end减小为mid-1.
	如果相等则说明查到*/
		mid = (start+end)/2;
		if(list->data[mid]<key)
		{
			start = mid+1;
		}
		else if(list->data[mid]>key)
		{
			end = mid-1;
		}
		else
			return mid;
	}
	return -1;//全部查找完后还没找到,则返回-1 
}

 6.二分查找(递归法)

int binarySearchRecursion(List *list,int key,int start,int end)
{/*参数一:列表指针
参数二:要查找的元素
参数三:开始查找的元素下标
参数四:结束查找的元素下标*/
	if(start==end)//递归出口,start=end时说明数组查找到最后了 
	{
		if(list->data[start]==key)//最后查找的元素如果等于key,则找到元素,直接返回 
			return start;
		else
			return -1;//没有则返回-1,说明该数组中不存在key 
	}
	int mid = (start+end)/2;
	if(list->data[mid]>key)//如果查找元素小于中间元素,说明查找元素可能在数组的前一半内,此时end减小为mid-1.
		return binarySearchRecursion(list,key,start,end-1);//递归查找 
	else if(list->data[mid]<key)//如果查找元素大于中间元素,说明查找元素可能在数组后一半内,此时start增加为mid+1.
		return binarySearchRecursion(list,key,start+1,end);//递归查找 
	else
		return mid;//相等,说明找到了,直接返回该元素的下标 
}

7.主函数

int main()
{
	List *list = initList(9);//初始化定义9个元素的数组 
	int i,key;
	for(i=1;i<=9;i++)
		listAdd(list,i);//写入1-9的元素 
	printf("列表内有以下元素:\n");
	printList(list);//遍历输出列表内所有元素 
	printf("请输入要查找的元素:");
	scanf("%d",&key);
	int n;
	n = binarySearch(list,key);//非递归二分查找 
	if(n==-1)
		printf("未查找到该元素\n");
	else
		printf("查找到该元素:%d\n",list->data[n]); 
	printf("请输入要查找的元素:");
	scanf("%d",&key);
	n = binarySearchRecursion(list,key,0,list->num-1);//递归二分查找 
	if(n==-1)
		printf("未查找到该元素\n");
	else
		printf("查找到该元素:%d\n",list->data[n]); 
	return 0;
}

 完整代码:

#include <stdio.h>
#include <stdlib.h>
/*定义列表结构体*/
typedef struct List
{
	int *data;//数组 
	int length;//总长度 
	int num;//当前长度 
}List;
/*初始化列表*/
List *initList(int length)
{/*参数length:数组总长度空间*/
	List *list = (List*)malloc(sizeof(List));//申请列表的结构体空间 
	list->data = (int*)malloc(sizeof(int)*length);//申请列表结构体内的data空间 
	list->length = length;//将总长度写入列表结构体 
	list->num = 0;//当前元素个数初始为0 
	return list;//函数指针,返回一个指针 
}
/*向列表结构体中写入元素*/
void listAdd(List *list,int data)
{/*参数一:列表指针
参数二:要写入的元素*/
	list->data[list->num] = data;//把当前元素的个数作为下标,将元素写入列表结构体 
	list->num += 1;//列表结构体中当前元素个数加一 
}
/*遍历输出*/
void printList(List *list)
{/*参数list:列表指针*/
	int i;
	for(i=0;i<list->num;i++)//按序输出列表中的元素 
		printf("%d ",list->data[i]);
	printf("\n");
}
/*二分查找*/
int binarySearch(List *list,int key)
{/*参数一:列表指针
参数二:要查找的元素*/
	int start=0,end=list->data[list->num-1];//初始时start为0,end为数组最后一个元素的下标 
	int mid;
	int i;
	while(start<=end)
	{/*如果查找元素大于中间元素,说明查找元素可能在数组后一半内,
	此时start增加为mid+1.
	如果查找元素小于中间元素,说明查找元素可能在数组的前一半内,
	此时end减小为mid-1.
	如果相等则说明查到*/
		mid = (start+end)/2;
		if(list->data[mid]<key)
		{
			start = mid+1;
		}
		else if(list->data[mid]>key)
		{
			end = mid-1;
		}
		else
			return mid;
	}
	return -1;//全部查找完后还没找到,则返回-1 
}
/*二分查找(递归法)*/
int binarySearchRecursion(List *list,int key,int start,int end)
{/*参数一:列表指针
参数二:要查找的元素
参数三:开始查找的元素下标
参数四:结束查找的元素下标*/
	if(start==end)//递归出口,start=end时说明数组查找到最后了 
	{
		if(list->data[start]==key)//最后查找的元素如果等于key,则找到元素,直接返回 
			return start;
		else
			return -1;//没有则返回-1,说明该数组中不存在key 
	}
	int mid = (start+end)/2;
	if(list->data[mid]>key)//如果查找元素小于中间元素,说明查找元素可能在数组的前一半内,此时end减小为mid-1.
		return binarySearchRecursion(list,key,start,end-1);//递归查找 
	else if(list->data[mid]<key)//如果查找元素大于中间元素,说明查找元素可能在数组后一半内,此时start增加为mid+1.
		return binarySearchRecursion(list,key,start+1,end);//递归查找 
	else
		return mid;//相等,说明找到了,直接返回该元素的下标 
}
int main()
{
	List *list = initList(9);//初始化定义9个元素的数组 
	int i,key;
	for(i=1;i<=9;i++)
		listAdd(list,i);//写入1-9的元素 
	printf("列表内有以下元素:\n");
	printList(list);//遍历输出列表内所有元素 
	printf("请输入要查找的元素:");
	scanf("%d",&key);
	int n;
	n = binarySearch(list,key);//非递归二分查找 
	if(n==-1)
		printf("未查找到该元素\n");
	else
		printf("查找到该元素:%d\n",list->data[n]); 
	printf("请输入要查找的元素:");
	scanf("%d",&key);
	n = binarySearchRecursion(list,key,0,list->num-1);//递归二分查找 
	if(n==-1)
		printf("未查找到该元素\n");
	else
		printf("查找到该元素:%d\n",list->data[n]); 
	return 0;
}

 运行结果:

 

 

 

### 关于C语言实现二分查找算法 以下是基于提供的引用以及专业知识所整理的关于如何用C语言实现二分查找算法的内容。 #### 什么是二分查找二分查找是一种高效的查找方法,适用于已排序的数据集合。其基本原理是从中间位置开始比较目标值与当前元素大小关系,从而缩小搜索范围至左半部分或右半部分继续执行相同逻辑直至找到目标或者确认不存在该目标[^1]。 #### C语言实现二分查找的关键点 在使用C语言编写二分查找时需注意以下几点: - 数据集必须事先按照升序或降序排列好; - 定义三个指针变量low、high和mid来跟踪待查区间两端及其中心位置; - 循环条件应设置为`while (low <= high)`以确保覆盖整个可能区域[^2]; 下面给出一个完整的C语言版本的二分查找函数: ```c #include <stdio.h> // 声明二分查找函数原型 int binarySearch(int array[], int size, int target); int main() { // 初始化测试数组并设定要找的目标数值 int data[] = {1, 3, 5, 7, 9}; int n = sizeof(data)/sizeof(data[0]); int key; printf("Enter the number to search:"); scanf("%d", &key); // 调用二分查找函数获取索引结果 int index = binarySearch(data, n, key); if(index != -1){ printf("Element found at position %d.\n", index+1); }else{ printf("Element not present in the array.\n"); } return 0; } // 定义实际的二分查找功能 int binarySearch(int array[], int size, int target) { int low = 0; int high = size - 1; while(low <= high){ int mid = low + ((high-low)>>1); if(array[mid]==target){ return mid; // 成功匹配返回下标 } if(target<array[mid]){ high=mid-1; // 更新上限边界 } else{ low=mid+1; // 更新下限边界 } } return -1; // 查无此数则返回负一表示失败 } ``` 上述代码展示了标准形式下的静态数组上运用迭代方式完成的一次典型二分查找过程[^3]。 #### 函数解释说明 这段程序首先定义了一个名为 `binarySearch` 的辅助函数用于接收参数列表包括原始整型数组地址、有效长度以及期望定位的对象值。接着通过不断调整左右端点直到两者交叉结束循环判定是否存在满足条件的位置。如果存在,则反馈具体偏移量加一作为最终答案展示给用户查看;反之输出提示信息告知未发现对应项。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值