分治与递归算法的应用
二分搜索算法
问题描述:设a[0:n-1]是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。并对自己的程序进行复杂性分析。
算法设计:已知a[0:n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。
代码如下:
View Code
1 #include<iostream>
2 using namespace std;
3 int n;
4 void Search(int a[],int x)
5 {
6 int low=0,high=n-1,mid,flag=0;
7 while(low<=high)
8 {
9 mid=(low+high)/2;
10 if(a[mid]==x)
11 {
12 flag=1;
13 cout<<x<<"在数组中,其位置是:"<<mid<<endl;
14 break;
15 }
16 else if(a[mid]>x) high=mid-1;
17 else low=mid+1;
18 }
19 if(flag==0)
20 {
21 cout<<x<<"不在数组中:";
22 if(a[mid]>x)
23 {
24 if(mid>0)cout<<" 小于其的最大元素的位置为:"<<mid-1<<endl;
25 else cout<<"数组中没有小于该元素的最大元素"<<endl;
26 cout<<"大于其的最小元素的位置为:"<<mid<<endl;
27 }
28 else {
29 cout<<"小于其的最大元素的位置为:"<<mid<<endl;
30 if(mid<n-1)cout<<"大于其的最小元素的位置为:"<<mid+1<<endl;
31 else cout<<"数组中没有大于该元素的最小元素"<<endl;
32 }
33 }
34 }
35
36 int main()
37 {
38 int a[1001],i,x;
39 while(cin>>n)
40 {
41 cout<<"请输入已经排好序的数组元素:"<<endl;
42 for(i=0;i<n;i++)
43 cin>>a[i];
44 cout<<"请输入需要查找的元素:";
45 cin>>x;
46 Search(a,x);
47 cout<<endl;
48 }
49 return 0;
50 }
2 using namespace std;
3 int n;
4 void Search(int a[],int x)
5 {
6 int low=0,high=n-1,mid,flag=0;
7 while(low<=high)
8 {
9 mid=(low+high)/2;
10 if(a[mid]==x)
11 {
12 flag=1;
13 cout<<x<<"在数组中,其位置是:"<<mid<<endl;
14 break;
15 }
16 else if(a[mid]>x) high=mid-1;
17 else low=mid+1;
18 }
19 if(flag==0)
20 {
21 cout<<x<<"不在数组中:";
22 if(a[mid]>x)
23 {
24 if(mid>0)cout<<" 小于其的最大元素的位置为:"<<mid-1<<endl;
25 else cout<<"数组中没有小于该元素的最大元素"<<endl;
26 cout<<"大于其的最小元素的位置为:"<<mid<<endl;
27 }
28 else {
29 cout<<"小于其的最大元素的位置为:"<<mid<<endl;
30 if(mid<n-1)cout<<"大于其的最小元素的位置为:"<<mid+1<<endl;
31 else cout<<"数组中没有大于该元素的最小元素"<<endl;
32 }
33 }
34 }
35
36 int main()
37 {
38 int a[1001],i,x;
39 while(cin>>n)
40 {
41 cout<<"请输入已经排好序的数组元素:"<<endl;
42 for(i=0;i<n;i++)
43 cin>>a[i];
44 cout<<"请输入需要查找的元素:";
45 cin>>x;
46 Search(a,x);
47 cout<<endl;
48 }
49 return 0;
50 }
找数:
问题描述:设n个不同的整数排好序后存于a[0:n-1]中。若存在一个下标0≤i<n,使得a[i]=i。设计一个有效算法找到这个下标。要求算法在最坏情况下的计算时间为O(logn)。
算法设计:由于题目要求算法在最坏情况下的计算时间为O(logn),故不能一个一个元素判断。数组a 中的元素各不相同而且还是排好序的,如果存在多个下标0≤i<n,使得a[i]=i,那么这几个元素在数组中是连续的。故首先应找到其中一个满足条件的元素,可以用二分查找,然后根据是连续的求出其他的满足条件的元素。另外还有种情况是数组中不存在这样的元素。
代码如下:
View Code
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 int n,flag;
5 bool cmp(int a,int b)
6 {
7 return a<b;
8 }
9 int Search(int a[])//找到满足条件的一个
10 {
11 int low=0,high=n-1,mid;
12 while(low<=high)
13 {
14 mid=(low+high)/2;
15 if(a[mid]==mid){ flag=1; return mid; }
16 else if(a[mid]>mid) high=mid-1;
17 else low=mid+1;
18 }
19 return 0;
20 }
21 int main()
22 {
23 int a[1001],i,j,k,b[1001];//数组b 存放满足条件的元素
24 while(cin>>n)
25 {
26 cout<<"请输入已经排好序的数组元素:"<<endl;
27 for(i=0;i<n;i++)
28 cin>>a[i];
29 if(a[0]>0) { cout<<"不存在这样的元素"<<endl; continue; }
30 flag=0;//flag 标记是否存在这样的元素
31 k=Search(a);
32 int m=k-1;
33 b[0]=k;j=0;
34 if(flag) //存在一个这样的元素
35 {
36 while(m>=0&&a[m]==m)//找比mid小的连续的数放在数组b中
37 {
38 b[++j]=m;
39 m--;
40 }
41 k++;
42 while(k<n&&a[k]==k)//找比mid大的连续的数放在数组b中
43 {
44 b[++j]=k;
45 k++;
46 }
47 sort(b,b+j+1,cmp);//从小到大排序
48 cout<<"满足条件的元素如下:";
49 for(i=0;i<=j;i++)
50 cout<<b[i]<<" ";
51 cout<<endl;
52 }
53 else cout<<"不存在这样的元素"<<endl;
54 }
55 return 0;
56 }
2 #include<algorithm>
3 using namespace std;
4 int n,flag;
5 bool cmp(int a,int b)
6 {
7 return a<b;
8 }
9 int Search(int a[])//找到满足条件的一个
10 {
11 int low=0,high=n-1,mid;
12 while(low<=high)
13 {
14 mid=(low+high)/2;
15 if(a[mid]==mid){ flag=1; return mid; }
16 else if(a[mid]>mid) high=mid-1;
17 else low=mid+1;
18 }
19 return 0;
20 }
21 int main()
22 {
23 int a[1001],i,j,k,b[1001];//数组b 存放满足条件的元素
24 while(cin>>n)
25 {
26 cout<<"请输入已经排好序的数组元素:"<<endl;
27 for(i=0;i<n;i++)
28 cin>>a[i];
29 if(a[0]>0) { cout<<"不存在这样的元素"<<endl; continue; }
30 flag=0;//flag 标记是否存在这样的元素
31 k=Search(a);
32 int m=k-1;
33 b[0]=k;j=0;
34 if(flag) //存在一个这样的元素
35 {
36 while(m>=0&&a[m]==m)//找比mid小的连续的数放在数组b中
37 {
38 b[++j]=m;
39 m--;
40 }
41 k++;
42 while(k<n&&a[k]==k)//找比mid大的连续的数放在数组b中
43 {
44 b[++j]=k;
45 k++;
46 }
47 sort(b,b+j+1,cmp);//从小到大排序
48 cout<<"满足条件的元素如下:";
49 for(i=0;i<=j;i++)
50 cout<<b[i]<<" ";
51 cout<<endl;
52 }
53 else cout<<"不存在这样的元素"<<endl;
54 }
55 return 0;
56 }