zoukankan      html  css  js  c++  java
  • C++分治策略实现二分搜索

    问题描述:

            给定已排好序的n个元素组成的数组,现要利用二分搜索算法判断特定元素x是否在该有序数组中。

    细节须知:

    (1)由于可能需要对分治策略实现二分搜索的算法效率进行评估,故使用大量的随机数对算法进行实验(生成随机数的方法见前篇随笔)。

    (2)由于二分搜索需要数据为有序的,故在进行搜索前利用函数库中sort函数对输入的数据进行排序。

    (3)代码主要用到的是经典的二分查找加上递归

    (4)其中limit为所要从随机数文件中提取的数据的数量,以此为限来决定算法需要在多少个数据中进行搜索。

    (5)为了使代码更人性化,加入了查找成功与失败的提醒,主要区别于Search函数中的返回值,若查找成功则返回1(满足1>0,即为查找成功),其余则返回0,即为查找失败

    (6)通过clock函数对算法运行的时间进行计算以评估算法效率

    算法原理:

           假设搜索范围为数组a中的n个元素,要搜索的元素为x。

           将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较。如果x=a[n/2],则找到x,算法终止。如果x<a[n/2],则只要在数组a的左半部继续搜索x。如果x>a[n/2],则只要在数组a的右半部继续搜索x。以此不断地将搜索范围折半,从而实现采用分治策略进行二分搜索。

     1 #include <iostream>
    2 #include <fstream> 3 #include <cstdlib> 4 #include <ctime> 5 #include <algorithm> 6 using namespace std; 7 #define limit 100000 8 9 int Search(int R[],int low,int high,int k) //low表示当前查找的范围下界、high表示当前查找范围的上界,k为所要查找的内容 10 { 11 int mid; 12 13 if (low<=high){ //查找区间存在一个及以上元素 14 mid=(low+high)/2; //求中间位置 15 if (R[mid]==k) //查找成功返回1 16 return 1; 17 if (R[mid]>k) //在R[low..mid-1]中递归查找 18 Search(R,low,mid-1,k); 19 else //在R[mid+1..high]中递归查找 20 Search(R,mid+1,high,k); 21 } 22 else 23 return 0; 24 } 25 26 int main(void) 27 { 28 ifstream fin; 29 int x; 30 int i; 31 int a[limit]; 32 int result; 33 34 fin.open("random_number.txt"); 35 if(!fin){ 36 cerr<<"Can not open file 'random_number.txt' "<<endl; 37 return -1; 38 } 39 40 time_t first, last; 41 42 for(i=0; i<limit; i++){ 43 fin>>a[i]; 44 } 45 fin.close(); 46 47 sort(a,a+limit); 48 49 cout<<"Please enter the number you want to find:"; 50 cin>>x; 51 52 first = clock(); 53 54 result = Search(a,0,limit-1,x); 55 56 if(result>0) 57 cout<<"Search success!"<<endl; 58 else 59 cout<<"Can not find it!"<<endl; 60 61 last = clock(); 62 63 cout<<"Time cost: "<<last-first<<endl; 64 65 return 0; 66 }

    程序设计思路:

            若x等于中间项,则退出。否则,

          (1)将数组划分为两个子数组,其大小大约为原数组的一半。如果x小于中间项,则选择左子数组;如果x大于中间项,则选择右子数组。

          (2)确定x是否在该子数组中,以解决该子数组。如果该子数组不够小,则进行递归处理。

          (3)由子数组的答案获得原数组的答案。

    结果数据格式为time_t格式相减得到的长整型。

    时间复杂性分析:

          假设搜索范围为数组a中的n个元素,要搜索的元素为x。

          将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较。如果x=a[n/2],则找到x,算法终止。如果x<a[n/2],则只要在数组a的左半部继续搜索x。如果x>a[n/2],则只要在数组a的右半部继续搜索x。以此不断地将搜索范围折半,从而实现采用分治策略进行二分搜索。

          其中,每执行一次算法的循环,待搜索数组的大小减少一半。在最坏情况下(即x大于所有数组项),如果n是2的幂,而且x大于所有数组项目,那每次调用生成的实例恰好为原实例的一半;若n=1,且x大于这个唯一数组项目,会将x与此项目进行比较,后面是在low>high条件下的一次递归调用。因而,确定递推关系:

    W(n)=W(n/2)+1 (n>1,n为2的幂)

    W(1)=1

          由Master方法可以得到

    W(n)=lgn+1

         如果n不仅局限于2的幂,则

    W(n)=⌊lgn⌋+1∈O(lgn)

    其中⌊y⌋表示小于或等于y的最大整数。

  • 相关阅读:
    苹果IPhone真机开发调试
    Unity3d 错误提示 GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced
    Unity编辑器环境在Inspector面板中显示变量
    微信小程序开发
    Android 9.0 Http不能访问网络
    c#传不确定的参数个数,比如int型
    玩转@Git三剑客
    白话法律42讲-为程序员打造的专属法律武器
    uSurvival 1.41多人在线生存逃杀吃鸡类游戏源码
    NGUI: Next-Gen UI 2018.3.0f
  • 原文地址:https://www.cnblogs.com/Jesse-Cavendish/p/11615842.html
Copyright © 2011-2022 走看看