分治与递归算法的应用

二分搜索算法

问题描述:设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 }

 

找数

问题描述:设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= 1return 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 }

 

你可能感兴趣的:(算法)