首页 > 技术文章 > 算法第二章上机实验报告

lqx739744996 2019-09-22 23:31 原文

梁其星 20181003115 软工1803

一. 实践题目

7-2 改写二分搜索算法 (20 )

输入格式:

输入有两行:

第一行是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

 

.问题描述

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

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

 

三. 算法描述

1)#include <iostream>

2)using namespace std;

3)int binary(int a[],int n, int x)    

4){

5) int i=-1;

6) int j=0;

7) int temp=-1;

8) int left=0;

9) int right=n-1;

10)   int mid=0;

11)   while(left<=right)

12)   {

13)      mid=(left+right)/2;

14)      if(a[mid]==x)

15)      {

16)         temp=mid;

17)      }

18)      if(a[mid]<x)

19)      {

20)         left=mid+1;

21)      }

22)      else

23)      {

24)         right=mid-1;

25)      }

26)   }

27)  

28)   if(temp!=mid)//x不在数组中

29)   {

30)      i=right;

31)      j=left;

32)   }

33)   else 

34)   {

35)      i=temp;

36)      j=i;

37)   }

38)      cout<<i<<" "<<j;

39)   return 0;

40)}

41) 

42) 

43)int main()

44){

45)   int a[100];

46)   int b[100];

47)   int n,x;

48)   cin>>n>>x;

49)   for(int k=0;k<n;k++)

50)   {

51)      cin>>a[k];

52)   }

53)   binary(a,n,x);

54)   return 0;

分析:

①binary()函数与7-1方法一致,都是二分查找的步骤。在第28行开始利用临时变量temp来确定x是否为数组中的元素,若不是,则i,j不等且为临近的两个下标,若相等则把temp的值赋给i和j;

②因题目要求x小于全部值时输出的i,j值为-1和0,故此处我将i的初值赋值为-1便于我后续的输出

.算法时间及空间复杂度分析

将数组分为两部分,每次执行,数组规模减半,利用a[mid]与要寻找的x做比较,再确定x在哪半部分,故时间复杂度为O(log n)

非递归的二分查找,故空间复杂度为O(1)

.心得体会

此题在考虑特殊情况时做的不好,如x小于所有元素时的情况没有考虑到,i和j的初值赋得不好,程序的健壮性不足;

 

另一方面一开始读题的时候没有读仔细,以为输入的数组只要求非降序,故还多考虑了将输入的数组排序后再进行二分算法,实际上输入的数组就是升序的,故一开始的排序函数是冗余的;

 

二分算法的递归做法还不熟练,本题我用的是非递归的算法,这方面的知识需要加强。

推荐阅读