算法第一次实验报告:改写二分搜索算法的思路与分析

北战南征 提交于 2019-11-30 07:23:44
 改写二分搜索算法 思路与分析
 

题目来源:《计算机算法设计与分析》,王晓东

设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

输入格式:

输入有两行:

第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。

输出格式:

输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。当搜索元素在数组中时,i和j相同。 提示:若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值

输入样例:

在这里给出一组输入。例如:

6 5
2 4 6 8 10 12

输出样例:

在这里给出相应的输出。例如:

1 2——————————————————————————————————分割线——————————————————————————————————————————————思路:对于能够找到的元素,只需要把这个下标再输出一遍即可。对于找不到的元素,我们从优化过的二分搜索算法着手。众所周知,二分搜索算法的左指针和右指针会渐渐靠近,如果要输出这个数离得最近的两个下标,不妨分析left和right的接近情况。【这里我用的是left>right的递归条件,这样子做除了简化代码,还有特殊用处】

 

 括号左右是每次递归传递给形参的left right的值。

找0:(0,3)->(0,0)->(0,-1)

找4:(2,3)->(3,3)->(3,2)

找6:(2,3)->(3,3)->(4,3)

【记住:mid=(l+r)/2会取整,mid每次都要+1或者-1】

可以发现,只要把返回-1前的左右两个值调换顺序,就是正确的输出结果。这里我选择用全局变量保存。

然后在主函数里面判断是不是返回-1,以选择不同的输出方式。

时间复杂度:O(logn)【二分搜索,不解释】空间复杂度O(n)

收获:当你看到大概知道思路但是解不开的题目,在大脑里面模拟运行,可能就有意外收获。

最后附上代码

 

 1 #include<iostream>
 2 using namespace std;
 3 int leftnum=0;
 4 int rightnum=0;
 5 int binarysearch(int num[],int left,int right,int chazhao)
 6 {
 7     //findnum++;
 8     int mid;
 9     if(left>right)
10     {
11         //cout<<"zhaobudao";
12         leftnum = left;
13         rightnum = right;
14         return -1;
15     }
16     else
17     {
18         mid=(left+right)/2;
19         if(num[mid]==chazhao)
20         {
21             return mid;
22         }
23         else if(num[mid]!=chazhao)
24         {
25             if(chazhao>num[mid])
26             {
27                 return binarysearch(num,mid+1,right,chazhao);
28             }
29             else return binarysearch(num,left,mid-1,chazhao);
30         }
31     }
32 }
33 
34 
35 int main()
36 {
37     int num[1000];
38     int i,chazhao,n;
39     cin>>n;
40     cin>>chazhao;
41     for(i=0;i<n;i++)
42     {
43         cin>>num[i];
44     }
45     
46     int date = binarysearch(num,0,n-1,chazhao);
47     
48     if(date == -1){
49         cout<<rightnum<<" "<<leftnum;
50         
51     }
52     else
53     {
54         cout<<date<<" "<<date;
55     }
56 
57 } 

 

 

 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!