搜索算法(顺序、二分、索引)

本文深入解析了搜索算法的原理及应用,包括顺序查找、二分查找、索引查找和哈希查找,详细分析了每种算法的时间复杂度,并提供了代码实现。通过本文,读者将全面了解搜索算法的优缺点及其在不同场景下的适用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搜索算法

平均查找长度ASL

ASL=P1C1+P2C2+...+PnCnASL = P_{1}C_{1} + P_{2}C_{2} + ...+ P_{n}C_{n}ASL=P1C1+P2C2+...+PnCn
P_{n}: 查找第n个元素的概率
C_{n}:查找第n个元素的比较次数

常见的查询算法

  • 顺序查找
  • 二分查找
  • 索引查找
  • 哈希查找

1. 顺序查找

复杂度分析:
  • 最好情况: O(1)
  • 最差情况: O(n)
  • ASL=1n∑i=1ni=n+12ASL = \frac{1}{n}\sum_{i=1}^{n}i = \frac{n+1}{2}ASL=n1i=1ni=2n+1
代码:
typedef int ElemType;
int seqSearch(ElemType *table, int length, ElemType target){
  int i;
  for(i = 0; i < length ; i++){
    if(table[i] == target){
      return i;
    }
  }
  return -1;
}

2. 二分查找(折半)

要求

有序表

复杂度分析:
  • 最好情况: O(1)
  • 最差情况: O(log2n+1log_{2}n +1log2n+1)
  • ASL: 假设为满二叉树: 树高 h=log2(n+1)h = log_{2}(n+1)h=log2(n+1)
    ASL=1n∑i=1hi∗2i−1=n+1nlog2(n+1)−1ASL = \frac{1}{n} \sum_{i = 1}^{h}i *2^{i-1} = \frac{n+1}{n}log_{2}(n+1)-1ASL=n1i=1hi2i1=nn+1log2(n+1)1
代码:
typedef int ElemType;
int binarySearcch(ElemType *table, int length, ElemType target) {
  if(length <= 0) return -1;
  int low = 0, high = length - 1, mid = (high + low) / 2;

  while(low <= high) {
    if(target == table[mid]) return mid;
    else if(target < table[mid])
      high = mid -1;
    else low = mid + 1;

    mid = (low + high) / 2;
  }
  return -1;
}

3. 索引查找

要求
  • 建立索引, 根据索引定位, 每个索引划分一个块
  • 索引有序, 每个块内部也有序
  • 对索引表和每个块内都可以进行顺序查找或者二分查找
  • 即在索引表中查找, 再到块中查找.
复杂度分析:
  • 假设索引和快内都采用顺序搜索:
  • ASL = ASL(索引表) + ASL(块内)
  • 设表长为n, 每个块有r个元素, 可以分为s个块 , 粗略来说: r=nsr = \frac{n}{s}r=sn
    ASL=1s∑i=1si+1r∑j=1rj=s+r+22=12(ns+s)+1ASL = \frac{1}{s} \sum_{i = 1}^{s}i +\frac{1}{r} \sum_{j = 1}^{r}j = \frac {s+r+2}{2} = \frac{1}{2}(\frac{n}{s}+s)+1 ASL=s1i=1si+r1j=1rj=2s+r+2=21(sn+s)+1
代码:
typedef int Elemtype;

typedef struct index{
  Elemtype key;
  int index;
}Index;

int indexSearch(vector <Index> indexVec, Elemtype *table, Elemtype target) {
  //索引表中最后一个元素存储的index为table的最后一个元素的下标
  int i = 0;
  while(i < indexVec.size() - 1 && target > indexVec[i].key) i++;
  if( i == indexVec.size() - 1) return -1;

  int j = indexVec[i].index;
  // printf("块:%d\n",i );

  while(table[j] != target && j < indexVec[i+1].index) j++;
  if(target == table[j]) return j;
  return -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值