第2讲_分治算法和二分搜索算法1
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
利用分解出的子问题的解可以合并为该问题的解
分析:很显然此问题分解出的子问题相互独立,即在a[i] 的前面或后面查找x是独立的子问题,因此满足分治法的 第四个适用条件。
2
二分搜索基本思想:
是将n个元素分为个数大致相同的两半,取a[n/2]
与x进行比较。
如果x=a[n/2],则找到x,算法终止。
如果x<a[n/2],只要在数组a的左半部继续搜索x。
mid
6
7
8
9
right
mid left mid right
二分搜索的步骤: 1、确定三个关键下标的初值:left=0, right=8, mid=(left+right)/2; 2、判断要找的数x是否等于a[mid] ① x==a[mid] 找到,结束 ② x<a[mid] 在左半部查找x right=mid-1; mid=(left+right)/2; ③ x>a[mid] 在右半部查找x left=mid+1; mid=(left+right)/2;
9
递归法的程序代码 int find(int a[ ], int x, int left, int right) { int mid; if(left<=right) { mid=(left+right)/2; if(x==a[mid]) return mid; // 找到x,返回mid的值 else if(x>a[mid]) return find(a,x,mid+1,right); x大则查找数组中较大的一半 else return find(a,x,left,mid-1); x小则查找数组中较小的一半 } return -1; // 没找到时返回-1 }
// 没找到时返回-1
7
} return -1; }
2-2 二分搜索算法
程序代码
#include<stdio.h> #define N 10 // 符号常量定义,便于修改数组的大小 int find(int a[ ], int x, int left, int right); // 函数声明 int main( ) { int i, x, a[N], result; printf("\n 输入升序数组 a:\n"); for(i=0; i<N; i++) scanf("%d", &a[i]); printf(“输入要查找的数 x:"); scanf("%d", &x); result=find(a, x, 0, N-1); // 函数调用 if (result== -1) printf("%d is not found.\n", x); else printf("Find %d==a[%d]\n", x, result); }
10
11
mid leftmid left right mid
5
2-2 二分搜索算法
程序代码
#include<stdio.h> int find(int a[ ], int x, int n);// 函数声明 int main( ) { int a[ ]={1,2,3,4,5,6,7,8,9}; int n,x, b,c; printf("请输入想要查找的数:\n"); scanf("%d", &b); c=find(a, b,9); // 函数调用 if (c==-1) printf("%d is not found.\n", c); else printf("Find a[%d]=%d\n", c,b); return 0; }
2.3 二分搜索技术
本讲内容: (1) 二分搜索技术
1
二分搜索技术
给定已按升序排好序的n个元素a[0:n-1],现要 在这n个元素中找出一特定元素x。
分析:
该问题的规模缩小到一定的程度就可以容易地解决 该问题可以分解为若干个规模较小的相同问题 该问题所分解出的各个子问题是相互独立的
6
2-2 二分搜索算法
程序代码
int fun(int a[ ], int x, int n) { int mid; // 满足条件时进行二分搜索 while(left<=right) { mid=(left+right)/2; // 计算中间位置的下标 if(x==a[mid]) // 若x等于a[mid],表示找到 return mid; // 找到x,返回mid的值 if(x>a[mid]) // x大则查找数组中较大的一半 left=mid+1; else right=mid-1; // x小则查找数组中较小的一半
4
2-2 二分搜索算法---找不到的情况
前提条件:有一组数已经按从小到大(或从大到小)排序 例如:输入一个数x=10,在这组数查找是否有x
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]
1
left
2
3
4
5
mid
6
left
7
8
9
二分搜索的步骤: 1、确定三个关键下标的初值:left=0, right=8, mid=(left+right)/2; 2、判断要找的数x是否等于a[mid] ① x>a[mid] 在右半部查找x left=mid+1; mid=(left+right)/2;
8
2-2 用递归函数实现二分搜索算法
分析:若使用递归算法,需要获得递归的终止条件和 递推关系
递归函数的终止条件: 1. 搜索成功,即x == a[mid],返回 mid 即 left > right,返回 -1 2. 搜索不成功, 递归函数的递推关系: 返回mid find(a,x,mid+1,right) 1. 如果x>a[mid],left= + 1,返回 find(a,x,left,right) 2. 如果x<a[mid], 返回find(a,x,left,mid-1)
如果x>a[n/2],只要在数组a的右半部继续搜索x。 具体算法如下:
3
2-2 二分搜索算法
前Байду номын сангаас条件:有一组数已经按从小到大(或从大到小)排序 例如:输入一个数x=3,在这组数查找是否有x
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]
1
left
2
3
4
5