分治与递归算法的应用

二分搜索算法

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

 

posted @ 2011-11-01 14:30  笑巧  阅读(2782)  评论(0编辑  收藏  举报