二分查找
二分查找法是一种查找数据在数组中位置的方法。通常,使用循环遍历就可以找到数组中每一个需要找到的元素。但当数据内容很多时,遍历的效率就显得十分低下。因此引入二分查找的方法,大大缩小了查找的耗时。
在一个数组从小到大排序好的前提下,二分查找可以这么理解。
存在一个序列a[N],一个待查找的数num,先找到这个序列的中点a[mid],与num比较,若相等则返回下标mid;否则,a[mid] > num,说明待查找的数在左边,便舍弃右边,对左边继续二分查找。反之,a[mid] < num,则对右边的子系列再次进行二分查找。
- 数组的排序(并不重要)
- 这里使用的时冒泡排序
void sortNum(int a[],int n)
{
int i, j;
int min = a[0];
for (i = 0; i < n; i++)
{
for (j = 1; j < n; j++)
{
if (a[j] < a[j - 1])
{
min = a[j];
a[j] = a[j - 1];
a[j - 1] = min;
}
}
}
}
主函数
#include<stdio.h>
#define N 100
int findSameNum(int a[], int num, int n);
int main()
{
int n, i, a[N], num, sameNum = 0;
printf("输入数组的大小");
scanf("%d", &n);
printf("输入你想查找的数字");
scanf("%d", &num);
printf("输入排列好的数组的内容");
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
sameNum = findSameNum(a, num, n);
if (sameNum == 0)
printf("Not Find!");
else
printf("你查找的数字是第%d个", sameNum);
}
二分查找
我们需要的数据有三:数组a[],查找项目num,数组中元素个数n
这中方法的难点,就是在于函数什么时候停止。我们就需要用到极限的想法。如果只剩下一个数据,那么这个数据下标的左边和右边是相等的。在分一次后,左边的下标会大于右边的下标,这时程序结束。
一般方法
int findSameNum(int a[], int num, int n)
{
//规定中心,左边,右边
int mid = 0, left = 1, right = n;
while (left <= right)//循环停止的条件
{
mid = (left + right) / 2;
if (a[mid] > num)
right = mid - 1;
if (a[mid] < num)
left = mid + 1;
else//如果你要找的值刚好在中间,那就输出位置,跳出函数
return mid;
}
return 0;//没有找到需要的数
}
递归方法
对于递归这个东西,我是比较排斥的。虽然函数更简洁了一点,但是运行往往会调用很多空间,而且递归函数比较抽象,别人去理解确实麻烦。但也不得不承认,递归作为一个优质的算法,在掌握后能对程序每一步运行状态看得更透彻。
递归需要一个全新的函数,用来每次调用递归时得到不同的结果。我们需要提前声名a[], num, left, right,在后续操作中得以赋值改变。思路同上,只是写法更加简洁。
int BS(int a[], int num, int left,int right)
{
int mid;
if (left > right)//递归停止的条件
return 0;
mid = (right + left) / 2;
if (num == a[mid])
return mid;
else if (num > a[mid])
return BS(a, num, mid + 1, right);
else
return BS(a, num, left, mid - 1);
}
//函数接口
int findSameNum(int a[], int num, int n)
{
int left = 1, right = n;
return BS(a, num, left, right);
}
题目是书上的,所以可能和PTA上的题目的答案不太一样。PTA使用了顺序表,在函数结构上更加清晰。如果想看正确答案,给大家指路----->
我大哥的二分查找答案
不过,自己写出来的东西,确实更有亲切感。