搜索结构(静态)

  • 搜索,就是在数据集合中寻找满足某种条件的数据元素。最常见的一种方式是事先给定一个值,在集合中找出其关键码等于给定值的元素。搜索的结果通常有两种可能:一种可能是搜索成功,即找到满足条件的数据元素。这时,作为结果,可报告该元素在结构中的位置,还可以进一步给出该元素中的具体信息。后者在数据库中叫做检索。另一种可能是搜索不成功,或搜索失败。作为结果,也应该报告一些信息,如失败标志、失败位置等。
  • 通常称用于搜索的数据集合为搜索结构,它是由同一数据类型的元素(或记录)组成。在搜索结构中,每一个元素(或记录)称作对象,搜索结构可用对象类来定义。
  • 在每一个对象中由若干属性,其中应当有一个属性,其值可唯一地标识这个对象。他称为关键码。使用基于关键码的检索,搜索结果应是唯一的。但在实际应用时,搜索条件是多方面的,例如,图书馆中应该允许按书名搜索、按作者搜索,…这样,可以使用基于属性的搜索方法,但搜索结果可能不唯一。
  • 静态查找就是我们平时概念中的查找,是“真正的查找”。之所以说静态查找是真正的查找,因为在静态查找过程中仅仅是执行“查找”的操作,即:(1)查看某特定的关键字是否在表中(判断性查找);(2)检索某特定关键字数据元素的各种属性(检索性查找)。这两种操作都只是获取已经存在的一个表中的数据信息,不对表的数据元素和结构进行任何改变,这就是所谓的静态查找。
  • 动态查找不像是“查找”,更像是一个对表进行“创建、扩充、修改、删除”的过程。动态查找的过程中对表的操作会多两个动作:(1)首先也有一个“判断性查找”的过程,如果某特定的关键字在表中不存在,则按照一定的规则将其插入表中;(2)如果已经存在,则可以对其执行删除操作。动态查找的过程虽然只是多了“插入”和“删除”的操作,但是在对具体的表执行这两种操作时,往往并不是那么简单。

顺序搜索

顺序搜索是最基本的搜索方法之一。顺序搜索又称为线性搜索,主要用于在线性表中进行搜索。、

int ordersearch(int a[], int n, int des){
  int i;
  for(i=0; i<n; i++){
   if(des==a[i])
     return 1;
  }
 return 0;
}

基于有序顺序表的顺序搜索和折半搜索

//顺序搜索
int ordersearch(int a[], int n, int des){
  int i;
  for(i=0; i<n; i++){
   if(des==a[i])
     return 1;
   else if(des<a[i]) break;
  }
 return 0;
}
//折半搜索非递归实现
public int bsearch(int[] a, int n, int value) {  
    int low = 0;  int high = n - 1;  
    while (low <= high) {    
       int mid = (low + high) / 2;    
       if (a[mid] == value) {      
         return mid;
       } else if (a[mid] < value) {      
          low = mid + 1;    
       } else {      
          high = mid - 1;    
       }  
   }  
   return -1; 
}
// 二分查找的递归实现 
public int bsearch(int[] a, int n, int val) {  
    return bsearchInternally(a, 0, n - 1, val);
} 
private int bsearchInternally(int[] a, int low, int high, int value) {  
    if (low > high) return -1;  
    int mid =  low + ((high - low) >> 1);  
    if (a[mid] == value) {    
       return mid;  
    } else if (a[mid] < value) {    
       return bsearchInternally(a, mid+1, high, value);  
    } else {    
       return bsearchInternally(a, low, mid-1, value);  
    } 
}

斐波拉契搜索

若一个具有n个元素的有序表,n=F(k)-1,即比某个斐波拉契数少1.如果n不是正好等于某个斐波拉契数,可以增加一些虚元素,使其达到某个斐波拉契数。例如,n=F(7)-1=12,可取low=1,hight=n=12,mid=F(6)=8。

public static int fibonacciSearch(int[] a, int n, int key) {
          int low = 0;
          int high = n - 1;
  
          int F[] = new int[max_size];
          fibonacci(F);//构建斐波那契数组
  
          //计算 n 位于斐波那契数列的位置
          int k = 0;
          while (n > F[k] - 1)
             ++k;
 
         //将数组a扩展到F[k]-1的长度,即增加了虚元素
          int tmp[];
          tmp = new int[F[k] - 1];
          System.arraycopy(a, 0, tmp, 0, n);
 
          for (int i = n; i < F[k] - 1; ++i)
              tmp[i] = a[n - 1];//用数组最后一个元素扩展
 
          while (low <= high) {
              int mid = low + F[k - 1] - 1;//借助斐波纳契数确定位置,减1是low从0开始
              if (key < tmp[mid]) {
                  high = mid - 1;
                  k -= 1;
              } else if (tmp[mid] < key) {
                  low = mid + 1;
                  k -= 2;
              } else {
                  if (mid < n)
                      return mid;
                  else
                      return n - 1;
              }
          }
          tmp = null;
          return -1;
      }
  • 当n很大(n>10)时,这种搜索方法叫做黄金分割法,其平均性能比折半搜索好。但是最坏情况时,性能比折半搜索差。搜索成功的平均搜索长度也是O(log2n)。这种方法的优点时找中间点mid不需要做除法,只需做加减法即可。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值